2015-11-25 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob47ffd78eee600b28f686cd1865adc086c3197170
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "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, boolean_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 gfc_conv_loop_setup (&loop, &code->expr1->where);
456 gfc_mark_ss_chain_used (ss, 1);
458 /* Convert the arguments, checking for dependencies. */
459 gfc_copy_loopinfo_to_se (&loopse, &loop);
460 loopse.ss = ss;
462 /* For operator assignment, do dependency checking. */
463 if (dependency_check)
464 check_variable = ELEM_CHECK_VARIABLE;
465 else
466 check_variable = ELEM_DONT_CHECK_VARIABLE;
468 gfc_init_se (&depse, NULL);
469 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
470 code->ext.actual, check_variable);
472 gfc_add_block_to_block (&loop.pre, &depse.pre);
473 gfc_add_block_to_block (&loop.post, &depse.post);
475 /* Generate the loop body. */
476 gfc_start_scalarized_body (&loop, &body);
477 gfc_init_block (&block);
479 if (mask && count1)
481 /* Form the mask expression according to the mask. */
482 index = count1;
483 maskexpr = gfc_build_array_ref (mask, index, NULL);
484 if (invert)
485 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
486 TREE_TYPE (maskexpr), maskexpr);
489 /* Add the subroutine call to the block. */
490 gfc_conv_procedure_call (&loopse, code->resolved_sym,
491 code->ext.actual, code->expr1,
492 NULL);
494 if (mask && count1)
496 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
497 build_empty_stmt (input_location));
498 gfc_add_expr_to_block (&loopse.pre, tmp);
499 tmp = fold_build2_loc (input_location, PLUS_EXPR,
500 gfc_array_index_type,
501 count1, gfc_index_one_node);
502 gfc_add_modify (&loopse.pre, count1, tmp);
504 else
505 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
507 gfc_add_block_to_block (&block, &loopse.pre);
508 gfc_add_block_to_block (&block, &loopse.post);
510 /* Finish up the loop block and the loop. */
511 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
512 gfc_trans_scalarizing_loops (&loop, &body);
513 gfc_add_block_to_block (&se.pre, &loop.pre);
514 gfc_add_block_to_block (&se.pre, &loop.post);
515 gfc_add_block_to_block (&se.pre, &se.post);
516 gfc_cleanup_loop (&loop);
519 return gfc_finish_block (&se.pre);
523 /* Translate the RETURN statement. */
525 tree
526 gfc_trans_return (gfc_code * code)
528 if (code->expr1)
530 gfc_se se;
531 tree tmp;
532 tree result;
534 /* If code->expr is not NULL, this return statement must appear
535 in a subroutine and current_fake_result_decl has already
536 been generated. */
538 result = gfc_get_fake_result_decl (NULL, 0);
539 if (!result)
541 gfc_warning (0,
542 "An alternate return at %L without a * dummy argument",
543 &code->expr1->where);
544 return gfc_generate_return ();
547 /* Start a new block for this statement. */
548 gfc_init_se (&se, NULL);
549 gfc_start_block (&se.pre);
551 gfc_conv_expr (&se, code->expr1);
553 /* Note that the actually returned expression is a simple value and
554 does not depend on any pointers or such; thus we can clean-up with
555 se.post before returning. */
556 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
557 result, fold_convert (TREE_TYPE (result),
558 se.expr));
559 gfc_add_expr_to_block (&se.pre, tmp);
560 gfc_add_block_to_block (&se.pre, &se.post);
562 tmp = gfc_generate_return ();
563 gfc_add_expr_to_block (&se.pre, tmp);
564 return gfc_finish_block (&se.pre);
567 return gfc_generate_return ();
571 /* Translate the PAUSE statement. We have to translate this statement
572 to a runtime library call. */
574 tree
575 gfc_trans_pause (gfc_code * code)
577 tree gfc_int4_type_node = gfc_get_int_type (4);
578 gfc_se se;
579 tree tmp;
581 /* Start a new block for this statement. */
582 gfc_init_se (&se, NULL);
583 gfc_start_block (&se.pre);
586 if (code->expr1 == NULL)
588 tmp = build_int_cst (gfc_int4_type_node, 0);
589 tmp = build_call_expr_loc (input_location,
590 gfor_fndecl_pause_string, 2,
591 build_int_cst (pchar_type_node, 0), tmp);
593 else if (code->expr1->ts.type == BT_INTEGER)
595 gfc_conv_expr (&se, code->expr1);
596 tmp = build_call_expr_loc (input_location,
597 gfor_fndecl_pause_numeric, 1,
598 fold_convert (gfc_int4_type_node, se.expr));
600 else
602 gfc_conv_expr_reference (&se, code->expr1);
603 tmp = build_call_expr_loc (input_location,
604 gfor_fndecl_pause_string, 2,
605 se.expr, se.string_length);
608 gfc_add_expr_to_block (&se.pre, tmp);
610 gfc_add_block_to_block (&se.pre, &se.post);
612 return gfc_finish_block (&se.pre);
616 /* Translate the STOP statement. We have to translate this statement
617 to a runtime library call. */
619 tree
620 gfc_trans_stop (gfc_code *code, bool error_stop)
622 tree gfc_int4_type_node = gfc_get_int_type (4);
623 gfc_se se;
624 tree tmp;
626 /* Start a new block for this statement. */
627 gfc_init_se (&se, NULL);
628 gfc_start_block (&se.pre);
630 if (code->expr1 == NULL)
632 tmp = build_int_cst (gfc_int4_type_node, 0);
633 tmp = build_call_expr_loc (input_location,
634 error_stop
635 ? (flag_coarray == GFC_FCOARRAY_LIB
636 ? gfor_fndecl_caf_error_stop_str
637 : gfor_fndecl_error_stop_string)
638 : gfor_fndecl_stop_string,
639 2, build_int_cst (pchar_type_node, 0), tmp);
641 else if (code->expr1->ts.type == BT_INTEGER)
643 gfc_conv_expr (&se, code->expr1);
644 tmp = build_call_expr_loc (input_location,
645 error_stop
646 ? (flag_coarray == GFC_FCOARRAY_LIB
647 ? gfor_fndecl_caf_error_stop
648 : gfor_fndecl_error_stop_numeric)
649 : gfor_fndecl_stop_numeric_f08, 1,
650 fold_convert (gfc_int4_type_node, se.expr));
652 else
654 gfc_conv_expr_reference (&se, code->expr1);
655 tmp = build_call_expr_loc (input_location,
656 error_stop
657 ? (flag_coarray == GFC_FCOARRAY_LIB
658 ? gfor_fndecl_caf_error_stop_str
659 : gfor_fndecl_error_stop_string)
660 : gfor_fndecl_stop_string,
661 2, se.expr, se.string_length);
664 gfc_add_expr_to_block (&se.pre, tmp);
666 gfc_add_block_to_block (&se.pre, &se.post);
668 return gfc_finish_block (&se.pre);
672 tree
673 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
675 gfc_se se, argse;
676 tree stat = NULL_TREE, stat2 = NULL_TREE;
677 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
679 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
680 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
681 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
682 return NULL_TREE;
684 if (code->expr2)
686 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
687 gfc_init_se (&argse, NULL);
688 gfc_conv_expr_val (&argse, code->expr2);
689 stat = argse.expr;
691 else if (flag_coarray == GFC_FCOARRAY_LIB)
692 stat = null_pointer_node;
694 if (code->expr4)
696 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
697 gfc_init_se (&argse, NULL);
698 gfc_conv_expr_val (&argse, code->expr4);
699 lock_acquired = argse.expr;
701 else if (flag_coarray == GFC_FCOARRAY_LIB)
702 lock_acquired = null_pointer_node;
704 gfc_start_block (&se.pre);
705 if (flag_coarray == GFC_FCOARRAY_LIB)
707 tree tmp, token, image_index, errmsg, errmsg_len;
708 tree index = size_zero_node;
709 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
711 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
712 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
713 != INTMOD_ISO_FORTRAN_ENV
714 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
715 != ISOFORTRAN_LOCK_TYPE)
717 gfc_error ("Sorry, the lock component of derived type at %L is not "
718 "yet supported", &code->expr1->where);
719 return NULL_TREE;
722 gfc_get_caf_token_offset (&token, NULL, caf_decl, NULL_TREE, code->expr1);
724 if (gfc_is_coindexed (code->expr1))
725 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
726 else
727 image_index = integer_zero_node;
729 /* For arrays, obtain the array index. */
730 if (gfc_expr_attr (code->expr1).dimension)
732 tree desc, tmp, extent, lbound, ubound;
733 gfc_array_ref *ar, ar2;
734 int i;
736 /* TODO: Extend this, once DT components are supported. */
737 ar = &code->expr1->ref->u.ar;
738 ar2 = *ar;
739 memset (ar, '\0', sizeof (*ar));
740 ar->as = ar2.as;
741 ar->type = AR_FULL;
743 gfc_init_se (&argse, NULL);
744 argse.descriptor_only = 1;
745 gfc_conv_expr_descriptor (&argse, code->expr1);
746 gfc_add_block_to_block (&se.pre, &argse.pre);
747 desc = argse.expr;
748 *ar = ar2;
750 extent = integer_one_node;
751 for (i = 0; i < ar->dimen; i++)
753 gfc_init_se (&argse, NULL);
754 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
755 gfc_add_block_to_block (&argse.pre, &argse.pre);
756 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
757 tmp = fold_build2_loc (input_location, MINUS_EXPR,
758 integer_type_node, argse.expr,
759 fold_convert(integer_type_node, lbound));
760 tmp = fold_build2_loc (input_location, MULT_EXPR,
761 integer_type_node, extent, tmp);
762 index = fold_build2_loc (input_location, PLUS_EXPR,
763 integer_type_node, index, tmp);
764 if (i < ar->dimen - 1)
766 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
767 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
768 tmp = fold_convert (integer_type_node, tmp);
769 extent = fold_build2_loc (input_location, MULT_EXPR,
770 integer_type_node, extent, tmp);
775 /* errmsg. */
776 if (code->expr3)
778 gfc_init_se (&argse, NULL);
779 gfc_conv_expr (&argse, code->expr3);
780 gfc_add_block_to_block (&se.pre, &argse.pre);
781 errmsg = argse.expr;
782 errmsg_len = fold_convert (integer_type_node, argse.string_length);
784 else
786 errmsg = null_pointer_node;
787 errmsg_len = integer_zero_node;
790 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
792 stat2 = stat;
793 stat = gfc_create_var (integer_type_node, "stat");
796 if (lock_acquired != null_pointer_node
797 && TREE_TYPE (lock_acquired) != integer_type_node)
799 lock_acquired2 = lock_acquired;
800 lock_acquired = gfc_create_var (integer_type_node, "acquired");
803 if (op == EXEC_LOCK)
804 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
805 token, index, image_index,
806 lock_acquired != null_pointer_node
807 ? gfc_build_addr_expr (NULL, lock_acquired)
808 : lock_acquired,
809 stat != null_pointer_node
810 ? gfc_build_addr_expr (NULL, stat) : stat,
811 errmsg, errmsg_len);
812 else
813 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
814 token, index, image_index,
815 stat != null_pointer_node
816 ? gfc_build_addr_expr (NULL, stat) : stat,
817 errmsg, errmsg_len);
818 gfc_add_expr_to_block (&se.pre, tmp);
820 if (stat2 != NULL_TREE)
821 gfc_add_modify (&se.pre, stat2,
822 fold_convert (TREE_TYPE (stat2), stat));
824 if (lock_acquired2 != NULL_TREE)
825 gfc_add_modify (&se.pre, lock_acquired2,
826 fold_convert (TREE_TYPE (lock_acquired2),
827 lock_acquired));
829 return gfc_finish_block (&se.pre);
832 if (stat != NULL_TREE)
833 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
835 if (lock_acquired != NULL_TREE)
836 gfc_add_modify (&se.pre, lock_acquired,
837 fold_convert (TREE_TYPE (lock_acquired),
838 boolean_true_node));
840 return gfc_finish_block (&se.pre);
844 tree
845 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
847 gfc_se se, argse;
848 tree tmp;
849 tree images = NULL_TREE, stat = NULL_TREE,
850 errmsg = NULL_TREE, errmsglen = NULL_TREE;
852 /* Short cut: For single images without bound checking or without STAT=,
853 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
854 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
855 && flag_coarray != GFC_FCOARRAY_LIB)
856 return NULL_TREE;
858 gfc_init_se (&se, NULL);
859 gfc_start_block (&se.pre);
861 if (code->expr1 && code->expr1->rank == 0)
863 gfc_init_se (&argse, NULL);
864 gfc_conv_expr_val (&argse, code->expr1);
865 images = argse.expr;
868 if (code->expr2)
870 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
871 gfc_init_se (&argse, NULL);
872 gfc_conv_expr_val (&argse, code->expr2);
873 stat = argse.expr;
875 else
876 stat = null_pointer_node;
878 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
880 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
881 gfc_init_se (&argse, NULL);
882 gfc_conv_expr (&argse, code->expr3);
883 gfc_conv_string_parameter (&argse);
884 errmsg = gfc_build_addr_expr (NULL, argse.expr);
885 errmsglen = argse.string_length;
887 else if (flag_coarray == GFC_FCOARRAY_LIB)
889 errmsg = null_pointer_node;
890 errmsglen = build_int_cst (integer_type_node, 0);
893 /* Check SYNC IMAGES(imageset) for valid image index.
894 FIXME: Add a check for image-set arrays. */
895 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
896 && code->expr1->rank == 0)
898 tree cond;
899 if (flag_coarray != GFC_FCOARRAY_LIB)
900 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
901 images, build_int_cst (TREE_TYPE (images), 1));
902 else
904 tree cond2;
905 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
906 2, integer_zero_node,
907 build_int_cst (integer_type_node, -1));
908 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
909 images, tmp);
910 cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
911 images,
912 build_int_cst (TREE_TYPE (images), 1));
913 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
914 boolean_type_node, cond, cond2);
916 gfc_trans_runtime_check (true, false, cond, &se.pre,
917 &code->expr1->where, "Invalid image number "
918 "%d in SYNC IMAGES",
919 fold_convert (integer_type_node, images));
922 if (flag_coarray != GFC_FCOARRAY_LIB)
924 /* Set STAT to zero. */
925 if (code->expr2)
926 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
928 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
930 /* SYNC ALL => stat == null_pointer_node
931 SYNC ALL(stat=s) => stat has an integer type
933 If "stat" has the wrong integer type, use a temp variable of
934 the right type and later cast the result back into "stat". */
935 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
937 if (TREE_TYPE (stat) == integer_type_node)
938 stat = gfc_build_addr_expr (NULL, stat);
940 if(type == EXEC_SYNC_MEMORY)
941 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
942 3, stat, errmsg, errmsglen);
943 else
944 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
945 3, stat, errmsg, errmsglen);
947 gfc_add_expr_to_block (&se.pre, tmp);
949 else
951 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
953 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
954 3, gfc_build_addr_expr (NULL, tmp_stat),
955 errmsg, errmsglen);
956 gfc_add_expr_to_block (&se.pre, tmp);
958 gfc_add_modify (&se.pre, stat,
959 fold_convert (TREE_TYPE (stat), tmp_stat));
962 else
964 tree len;
966 gcc_assert (type == EXEC_SYNC_IMAGES);
968 if (!code->expr1)
970 len = build_int_cst (integer_type_node, -1);
971 images = null_pointer_node;
973 else if (code->expr1->rank == 0)
975 len = build_int_cst (integer_type_node, 1);
976 images = gfc_build_addr_expr (NULL_TREE, images);
978 else
980 /* FIXME. */
981 if (code->expr1->ts.kind != gfc_c_int_kind)
982 gfc_fatal_error ("Sorry, only support for integer kind %d "
983 "implemented for image-set at %L",
984 gfc_c_int_kind, &code->expr1->where);
986 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
987 images = se.expr;
989 tmp = gfc_typenode_for_spec (&code->expr1->ts);
990 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
991 tmp = gfc_get_element_type (tmp);
993 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
994 TREE_TYPE (len), len,
995 fold_convert (TREE_TYPE (len),
996 TYPE_SIZE_UNIT (tmp)));
997 len = fold_convert (integer_type_node, len);
1000 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1001 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1003 If "stat" has the wrong integer type, use a temp variable of
1004 the right type and later cast the result back into "stat". */
1005 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1007 if (TREE_TYPE (stat) == integer_type_node)
1008 stat = gfc_build_addr_expr (NULL, stat);
1010 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1011 5, fold_convert (integer_type_node, len),
1012 images, stat, errmsg, errmsglen);
1013 gfc_add_expr_to_block (&se.pre, tmp);
1015 else
1017 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1019 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1020 5, fold_convert (integer_type_node, len),
1021 images, gfc_build_addr_expr (NULL, tmp_stat),
1022 errmsg, errmsglen);
1023 gfc_add_expr_to_block (&se.pre, tmp);
1025 gfc_add_modify (&se.pre, stat,
1026 fold_convert (TREE_TYPE (stat), tmp_stat));
1030 return gfc_finish_block (&se.pre);
1034 /* Generate GENERIC for the IF construct. This function also deals with
1035 the simple IF statement, because the front end translates the IF
1036 statement into an IF construct.
1038 We translate:
1040 IF (cond) THEN
1041 then_clause
1042 ELSEIF (cond2)
1043 elseif_clause
1044 ELSE
1045 else_clause
1046 ENDIF
1048 into:
1050 pre_cond_s;
1051 if (cond_s)
1053 then_clause;
1055 else
1057 pre_cond_s
1058 if (cond_s)
1060 elseif_clause
1062 else
1064 else_clause;
1068 where COND_S is the simplified version of the predicate. PRE_COND_S
1069 are the pre side-effects produced by the translation of the
1070 conditional.
1071 We need to build the chain recursively otherwise we run into
1072 problems with folding incomplete statements. */
1074 static tree
1075 gfc_trans_if_1 (gfc_code * code)
1077 gfc_se if_se;
1078 tree stmt, elsestmt;
1079 locus saved_loc;
1080 location_t loc;
1082 /* Check for an unconditional ELSE clause. */
1083 if (!code->expr1)
1084 return gfc_trans_code (code->next);
1086 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1087 gfc_init_se (&if_se, NULL);
1088 gfc_start_block (&if_se.pre);
1090 /* Calculate the IF condition expression. */
1091 if (code->expr1->where.lb)
1093 gfc_save_backend_locus (&saved_loc);
1094 gfc_set_backend_locus (&code->expr1->where);
1097 gfc_conv_expr_val (&if_se, code->expr1);
1099 if (code->expr1->where.lb)
1100 gfc_restore_backend_locus (&saved_loc);
1102 /* Translate the THEN clause. */
1103 stmt = gfc_trans_code (code->next);
1105 /* Translate the ELSE clause. */
1106 if (code->block)
1107 elsestmt = gfc_trans_if_1 (code->block);
1108 else
1109 elsestmt = build_empty_stmt (input_location);
1111 /* Build the condition expression and add it to the condition block. */
1112 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1113 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1114 elsestmt);
1116 gfc_add_expr_to_block (&if_se.pre, stmt);
1118 /* Finish off this statement. */
1119 return gfc_finish_block (&if_se.pre);
1122 tree
1123 gfc_trans_if (gfc_code * code)
1125 stmtblock_t body;
1126 tree exit_label;
1128 /* Create exit label so it is available for trans'ing the body code. */
1129 exit_label = gfc_build_label_decl (NULL_TREE);
1130 code->exit_label = exit_label;
1132 /* Translate the actual code in code->block. */
1133 gfc_init_block (&body);
1134 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1136 /* Add exit label. */
1137 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1139 return gfc_finish_block (&body);
1143 /* Translate an arithmetic IF expression.
1145 IF (cond) label1, label2, label3 translates to
1147 if (cond <= 0)
1149 if (cond < 0)
1150 goto label1;
1151 else // cond == 0
1152 goto label2;
1154 else // cond > 0
1155 goto label3;
1157 An optimized version can be generated in case of equal labels.
1158 E.g., if label1 is equal to label2, we can translate it to
1160 if (cond <= 0)
1161 goto label1;
1162 else
1163 goto label3;
1166 tree
1167 gfc_trans_arithmetic_if (gfc_code * code)
1169 gfc_se se;
1170 tree tmp;
1171 tree branch1;
1172 tree branch2;
1173 tree zero;
1175 /* Start a new block. */
1176 gfc_init_se (&se, NULL);
1177 gfc_start_block (&se.pre);
1179 /* Pre-evaluate COND. */
1180 gfc_conv_expr_val (&se, code->expr1);
1181 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1183 /* Build something to compare with. */
1184 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1186 if (code->label1->value != code->label2->value)
1188 /* If (cond < 0) take branch1 else take branch2.
1189 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1190 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1191 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1193 if (code->label1->value != code->label3->value)
1194 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1195 se.expr, zero);
1196 else
1197 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1198 se.expr, zero);
1200 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1201 tmp, branch1, branch2);
1203 else
1204 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1206 if (code->label1->value != code->label3->value
1207 && code->label2->value != code->label3->value)
1209 /* if (cond <= 0) take branch1 else take branch2. */
1210 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1211 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1212 se.expr, zero);
1213 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1214 tmp, branch1, branch2);
1217 /* Append the COND_EXPR to the evaluation of COND, and return. */
1218 gfc_add_expr_to_block (&se.pre, branch1);
1219 return gfc_finish_block (&se.pre);
1223 /* Translate a CRITICAL block. */
1224 tree
1225 gfc_trans_critical (gfc_code *code)
1227 stmtblock_t block;
1228 tree tmp, token = NULL_TREE;
1230 gfc_start_block (&block);
1232 if (flag_coarray == GFC_FCOARRAY_LIB)
1234 token = gfc_get_symbol_decl (code->resolved_sym);
1235 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1236 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1237 token, integer_zero_node, integer_one_node,
1238 null_pointer_node, null_pointer_node,
1239 null_pointer_node, integer_zero_node);
1240 gfc_add_expr_to_block (&block, tmp);
1243 tmp = gfc_trans_code (code->block->next);
1244 gfc_add_expr_to_block (&block, tmp);
1246 if (flag_coarray == GFC_FCOARRAY_LIB)
1248 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1249 token, integer_zero_node, integer_one_node,
1250 null_pointer_node, null_pointer_node,
1251 integer_zero_node);
1252 gfc_add_expr_to_block (&block, tmp);
1256 return gfc_finish_block (&block);
1260 /* Return true, when the class has a _len component. */
1262 static bool
1263 class_has_len_component (gfc_symbol *sym)
1265 gfc_component *comp = sym->ts.u.derived->components;
1266 while (comp)
1268 if (strcmp (comp->name, "_len") == 0)
1269 return true;
1270 comp = comp->next;
1272 return false;
1276 /* Do proper initialization for ASSOCIATE names. */
1278 static void
1279 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1281 gfc_expr *e;
1282 tree tmp;
1283 bool class_target;
1284 bool unlimited;
1285 tree desc;
1286 tree offset;
1287 tree dim;
1288 int n;
1289 tree charlen;
1290 bool need_len_assign;
1292 gcc_assert (sym->assoc);
1293 e = sym->assoc->target;
1295 class_target = (e->expr_type == EXPR_VARIABLE)
1296 && (gfc_is_class_scalar_expr (e)
1297 || gfc_is_class_array_ref (e, NULL));
1299 unlimited = UNLIMITED_POLY (e);
1301 /* Assignments to the string length need to be generated, when
1302 ( sym is a char array or
1303 sym has a _len component)
1304 and the associated expression is unlimited polymorphic, which is
1305 not (yet) correctly in 'unlimited', because for an already associated
1306 BT_DERIVED the u-poly flag is not set, i.e.,
1307 __tmp_CHARACTER_0_1 => w => arg
1308 ^ generated temp ^ from code, the w does not have the u-poly
1309 flag set, where UNLIMITED_POLY(e) expects it. */
1310 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1311 && e->ts.u.derived->attr.unlimited_polymorphic))
1312 && (sym->ts.type == BT_CHARACTER
1313 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1314 && class_has_len_component (sym))));
1315 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1316 to array temporary) for arrays with either unknown shape or if associating
1317 to a variable. */
1318 if (sym->attr.dimension && !class_target
1319 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1321 gfc_se se;
1322 tree desc;
1323 bool cst_array_ctor;
1325 desc = sym->backend_decl;
1326 cst_array_ctor = e->expr_type == EXPR_ARRAY
1327 && gfc_constant_array_constructor_p (e->value.constructor);
1329 /* If association is to an expression, evaluate it and create temporary.
1330 Otherwise, get descriptor of target for pointer assignment. */
1331 gfc_init_se (&se, NULL);
1332 if (sym->assoc->variable || cst_array_ctor)
1334 se.direct_byref = 1;
1335 se.use_offset = 1;
1336 se.expr = desc;
1339 gfc_conv_expr_descriptor (&se, e);
1341 /* If we didn't already do the pointer assignment, set associate-name
1342 descriptor to the one generated for the temporary. */
1343 if (!sym->assoc->variable && !cst_array_ctor)
1345 int dim;
1347 gfc_add_modify (&se.pre, desc, se.expr);
1349 /* The generated descriptor has lower bound zero (as array
1350 temporary), shift bounds so we get lower bounds of 1. */
1351 for (dim = 0; dim < e->rank; ++dim)
1352 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1353 dim, gfc_index_one_node);
1356 /* If this is a subreference array pointer associate name use the
1357 associate variable element size for the value of 'span'. */
1358 if (sym->attr.subref_array_pointer)
1360 gcc_assert (e->expr_type == EXPR_VARIABLE);
1361 tmp = e->symtree->n.sym->backend_decl;
1362 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1363 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1364 gfc_add_modify (&se.pre, GFC_DECL_SPAN(desc), tmp);
1367 /* Done, register stuff as init / cleanup code. */
1368 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1369 gfc_finish_block (&se.post));
1372 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1373 arrays to be assigned directly. */
1374 else if (class_target && sym->attr.dimension
1375 && (sym->ts.type == BT_DERIVED || unlimited))
1377 gfc_se se;
1379 gfc_init_se (&se, NULL);
1380 se.descriptor_only = 1;
1381 /* In a select type the (temporary) associate variable shall point to
1382 a standard fortran array (lower bound == 1), but conv_expr ()
1383 just maps to the input array in the class object, whose lbound may
1384 be arbitrary. conv_expr_descriptor solves this by inserting a
1385 temporary array descriptor. */
1386 gfc_conv_expr_descriptor (&se, e);
1388 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1389 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1390 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1392 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1394 if (INDIRECT_REF_P (se.expr))
1395 tmp = TREE_OPERAND (se.expr, 0);
1396 else
1397 tmp = se.expr;
1399 gfc_add_modify (&se.pre, sym->backend_decl,
1400 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1402 else
1403 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1405 if (unlimited)
1407 /* Recover the dtype, which has been overwritten by the
1408 assignment from an unlimited polymorphic object. */
1409 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1410 gfc_add_modify (&se.pre, tmp,
1411 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1414 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1415 gfc_finish_block (&se.post));
1418 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1419 else if (gfc_is_associate_pointer (sym))
1421 gfc_se se;
1423 gcc_assert (!sym->attr.dimension);
1425 gfc_init_se (&se, NULL);
1427 /* Class associate-names come this way because they are
1428 unconditionally associate pointers and the symbol is scalar. */
1429 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1431 tree target_expr;
1432 /* For a class array we need a descriptor for the selector. */
1433 gfc_conv_expr_descriptor (&se, e);
1434 /* Needed to get/set the _len component below. */
1435 target_expr = se.expr;
1437 /* Obtain a temporary class container for the result. */
1438 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1439 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1441 /* Set the offset. */
1442 desc = gfc_class_data_get (se.expr);
1443 offset = gfc_index_zero_node;
1444 for (n = 0; n < e->rank; n++)
1446 dim = gfc_rank_cst[n];
1447 tmp = fold_build2_loc (input_location, MULT_EXPR,
1448 gfc_array_index_type,
1449 gfc_conv_descriptor_stride_get (desc, dim),
1450 gfc_conv_descriptor_lbound_get (desc, dim));
1451 offset = fold_build2_loc (input_location, MINUS_EXPR,
1452 gfc_array_index_type,
1453 offset, tmp);
1455 if (need_len_assign)
1457 if (e->symtree
1458 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1459 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1460 /* Use the original class descriptor stored in the saved
1461 descriptor to get the target_expr. */
1462 target_expr =
1463 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1464 else
1465 /* Strip the _data component from the target_expr. */
1466 target_expr = TREE_OPERAND (target_expr, 0);
1467 /* Add a reference to the _len comp to the target expr. */
1468 tmp = gfc_class_len_get (target_expr);
1469 /* Get the component-ref for the temp structure's _len comp. */
1470 charlen = gfc_class_len_get (se.expr);
1471 /* Add the assign to the beginning of the block... */
1472 gfc_add_modify (&se.pre, charlen,
1473 fold_convert (TREE_TYPE (charlen), tmp));
1474 /* and the oposite way at the end of the block, to hand changes
1475 on the string length back. */
1476 gfc_add_modify (&se.post, tmp,
1477 fold_convert (TREE_TYPE (tmp), charlen));
1478 /* Length assignment done, prevent adding it again below. */
1479 need_len_assign = false;
1481 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1483 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1484 && CLASS_DATA (e)->attr.dimension)
1486 /* This is bound to be a class array element. */
1487 gfc_conv_expr_reference (&se, e);
1488 /* Get the _vptr component of the class object. */
1489 tmp = gfc_get_vptr_from_expr (se.expr);
1490 /* Obtain a temporary class container for the result. */
1491 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1492 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1494 else
1496 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1497 which has the string length included. For CHARACTERS it is still
1498 needed and will be done at the end of this routine. */
1499 gfc_conv_expr (&se, e);
1500 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1503 tmp = TREE_TYPE (sym->backend_decl);
1504 tmp = gfc_build_addr_expr (tmp, se.expr);
1505 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1507 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1508 gfc_finish_block (&se.post));
1511 /* Do a simple assignment. This is for scalar expressions, where we
1512 can simply use expression assignment. */
1513 else
1515 gfc_expr *lhs;
1517 lhs = gfc_lval_expr_from_sym (sym);
1518 tmp = gfc_trans_assignment (lhs, e, false, true);
1519 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1522 /* Set the stringlength, when needed. */
1523 if (need_len_assign)
1525 gfc_se se;
1526 gfc_init_se (&se, NULL);
1527 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1529 /* What about deferred strings? */
1530 gcc_assert (!e->symtree->n.sym->ts.deferred);
1531 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1533 else
1534 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1535 gfc_get_symbol_decl (sym);
1536 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1537 : gfc_class_len_get (sym->backend_decl);
1538 /* Prevent adding a noop len= len. */
1539 if (tmp != charlen)
1541 gfc_add_modify (&se.pre, charlen,
1542 fold_convert (TREE_TYPE (charlen), tmp));
1543 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1544 gfc_finish_block (&se.post));
1550 /* Translate a BLOCK construct. This is basically what we would do for a
1551 procedure body. */
1553 tree
1554 gfc_trans_block_construct (gfc_code* code)
1556 gfc_namespace* ns;
1557 gfc_symbol* sym;
1558 gfc_wrapped_block block;
1559 tree exit_label;
1560 stmtblock_t body;
1561 gfc_association_list *ass;
1563 ns = code->ext.block.ns;
1564 gcc_assert (ns);
1565 sym = ns->proc_name;
1566 gcc_assert (sym);
1568 /* Process local variables. */
1569 gcc_assert (!sym->tlink);
1570 sym->tlink = sym;
1571 gfc_process_block_locals (ns);
1573 /* Generate code including exit-label. */
1574 gfc_init_block (&body);
1575 exit_label = gfc_build_label_decl (NULL_TREE);
1576 code->exit_label = exit_label;
1578 finish_oacc_declare (ns, sym, true);
1580 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1581 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1583 /* Finish everything. */
1584 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1585 gfc_trans_deferred_vars (sym, &block);
1586 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1587 trans_associate_var (ass->st->n.sym, &block);
1589 return gfc_finish_wrapped_block (&block);
1593 /* Translate the simple DO construct. This is where the loop variable has
1594 integer type and step +-1. We can't use this in the general case
1595 because integer overflow and floating point errors could give incorrect
1596 results.
1597 We translate a do loop from:
1599 DO dovar = from, to, step
1600 body
1601 END DO
1605 [Evaluate loop bounds and step]
1606 dovar = from;
1607 if ((step > 0) ? (dovar <= to) : (dovar => to))
1609 for (;;)
1611 body;
1612 cycle_label:
1613 cond = (dovar == to);
1614 dovar += step;
1615 if (cond) goto end_label;
1618 end_label:
1620 This helps the optimizers by avoiding the extra induction variable
1621 used in the general case. */
1623 static tree
1624 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1625 tree from, tree to, tree step, tree exit_cond)
1627 stmtblock_t body;
1628 tree type;
1629 tree cond;
1630 tree tmp;
1631 tree saved_dovar = NULL;
1632 tree cycle_label;
1633 tree exit_label;
1634 location_t loc;
1636 type = TREE_TYPE (dovar);
1638 loc = code->ext.iterator->start->where.lb->location;
1640 /* Initialize the DO variable: dovar = from. */
1641 gfc_add_modify_loc (loc, pblock, dovar,
1642 fold_convert (TREE_TYPE(dovar), from));
1644 /* Save value for do-tinkering checking. */
1645 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1647 saved_dovar = gfc_create_var (type, ".saved_dovar");
1648 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1651 /* Cycle and exit statements are implemented with gotos. */
1652 cycle_label = gfc_build_label_decl (NULL_TREE);
1653 exit_label = gfc_build_label_decl (NULL_TREE);
1655 /* Put the labels where they can be found later. See gfc_trans_do(). */
1656 code->cycle_label = cycle_label;
1657 code->exit_label = exit_label;
1659 /* Loop body. */
1660 gfc_start_block (&body);
1662 /* Main loop body. */
1663 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1664 gfc_add_expr_to_block (&body, tmp);
1666 /* Label for cycle statements (if needed). */
1667 if (TREE_USED (cycle_label))
1669 tmp = build1_v (LABEL_EXPR, cycle_label);
1670 gfc_add_expr_to_block (&body, tmp);
1673 /* Check whether someone has modified the loop variable. */
1674 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1676 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1677 dovar, saved_dovar);
1678 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1679 "Loop variable has been modified");
1682 /* Exit the loop if there is an I/O result condition or error. */
1683 if (exit_cond)
1685 tmp = build1_v (GOTO_EXPR, exit_label);
1686 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1687 exit_cond, tmp,
1688 build_empty_stmt (loc));
1689 gfc_add_expr_to_block (&body, tmp);
1692 /* Evaluate the loop condition. */
1693 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, dovar,
1694 to);
1695 cond = gfc_evaluate_now_loc (loc, cond, &body);
1697 /* Increment the loop variable. */
1698 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1699 gfc_add_modify_loc (loc, &body, dovar, tmp);
1701 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1702 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1704 /* The loop exit. */
1705 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1706 TREE_USED (exit_label) = 1;
1707 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1708 cond, tmp, build_empty_stmt (loc));
1709 gfc_add_expr_to_block (&body, tmp);
1711 /* Finish the loop body. */
1712 tmp = gfc_finish_block (&body);
1713 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1715 /* Only execute the loop if the number of iterations is positive. */
1716 if (tree_int_cst_sgn (step) > 0)
1717 cond = fold_build2_loc (loc, LE_EXPR, boolean_type_node, dovar,
1718 to);
1719 else
1720 cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node, dovar,
1721 to);
1722 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, tmp,
1723 build_empty_stmt (loc));
1724 gfc_add_expr_to_block (pblock, tmp);
1726 /* Add the exit label. */
1727 tmp = build1_v (LABEL_EXPR, exit_label);
1728 gfc_add_expr_to_block (pblock, tmp);
1730 return gfc_finish_block (pblock);
1733 /* Translate the DO construct. This obviously is one of the most
1734 important ones to get right with any compiler, but especially
1735 so for Fortran.
1737 We special case some loop forms as described in gfc_trans_simple_do.
1738 For other cases we implement them with a separate loop count,
1739 as described in the standard.
1741 We translate a do loop from:
1743 DO dovar = from, to, step
1744 body
1745 END DO
1749 [evaluate loop bounds and step]
1750 empty = (step > 0 ? to < from : to > from);
1751 countm1 = (to - from) / step;
1752 dovar = from;
1753 if (empty) goto exit_label;
1754 for (;;)
1756 body;
1757 cycle_label:
1758 dovar += step
1759 countm1t = countm1;
1760 countm1--;
1761 if (countm1t == 0) goto exit_label;
1763 exit_label:
1765 countm1 is an unsigned integer. It is equal to the loop count minus one,
1766 because the loop count itself can overflow. */
1768 tree
1769 gfc_trans_do (gfc_code * code, tree exit_cond)
1771 gfc_se se;
1772 tree dovar;
1773 tree saved_dovar = NULL;
1774 tree from;
1775 tree to;
1776 tree step;
1777 tree countm1;
1778 tree type;
1779 tree utype;
1780 tree cond;
1781 tree cycle_label;
1782 tree exit_label;
1783 tree tmp;
1784 stmtblock_t block;
1785 stmtblock_t body;
1786 location_t loc;
1788 gfc_start_block (&block);
1790 loc = code->ext.iterator->start->where.lb->location;
1792 /* Evaluate all the expressions in the iterator. */
1793 gfc_init_se (&se, NULL);
1794 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1795 gfc_add_block_to_block (&block, &se.pre);
1796 dovar = se.expr;
1797 type = TREE_TYPE (dovar);
1799 gfc_init_se (&se, NULL);
1800 gfc_conv_expr_val (&se, code->ext.iterator->start);
1801 gfc_add_block_to_block (&block, &se.pre);
1802 from = gfc_evaluate_now (se.expr, &block);
1804 gfc_init_se (&se, NULL);
1805 gfc_conv_expr_val (&se, code->ext.iterator->end);
1806 gfc_add_block_to_block (&block, &se.pre);
1807 to = gfc_evaluate_now (se.expr, &block);
1809 gfc_init_se (&se, NULL);
1810 gfc_conv_expr_val (&se, code->ext.iterator->step);
1811 gfc_add_block_to_block (&block, &se.pre);
1812 step = gfc_evaluate_now (se.expr, &block);
1814 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1816 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
1817 build_zero_cst (type));
1818 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
1819 "DO step value is zero");
1822 /* Special case simple loops. */
1823 if (TREE_CODE (type) == INTEGER_TYPE
1824 && (integer_onep (step)
1825 || tree_int_cst_equal (step, integer_minus_one_node)))
1826 return gfc_trans_simple_do (code, &block, dovar, from, to, step, exit_cond);
1829 if (TREE_CODE (type) == INTEGER_TYPE)
1830 utype = unsigned_type_for (type);
1831 else
1832 utype = unsigned_type_for (gfc_array_index_type);
1833 countm1 = gfc_create_var (utype, "countm1");
1835 /* Cycle and exit statements are implemented with gotos. */
1836 cycle_label = gfc_build_label_decl (NULL_TREE);
1837 exit_label = gfc_build_label_decl (NULL_TREE);
1838 TREE_USED (exit_label) = 1;
1840 /* Put these labels where they can be found later. */
1841 code->cycle_label = cycle_label;
1842 code->exit_label = exit_label;
1844 /* Initialize the DO variable: dovar = from. */
1845 gfc_add_modify (&block, dovar, from);
1847 /* Save value for do-tinkering checking. */
1848 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1850 saved_dovar = gfc_create_var (type, ".saved_dovar");
1851 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
1854 /* Initialize loop count and jump to exit label if the loop is empty.
1855 This code is executed before we enter the loop body. We generate:
1856 if (step > 0)
1858 countm1 = (to - from) / step;
1859 if (to < from)
1860 goto exit_label;
1862 else
1864 countm1 = (from - to) / -step;
1865 if (to > from)
1866 goto exit_label;
1870 if (TREE_CODE (type) == INTEGER_TYPE)
1872 tree pos, neg, tou, fromu, stepu, tmp2;
1874 /* The distance from FROM to TO cannot always be represented in a signed
1875 type, thus use unsigned arithmetic, also to avoid any undefined
1876 overflow issues. */
1877 tou = fold_convert (utype, to);
1878 fromu = fold_convert (utype, from);
1879 stepu = fold_convert (utype, step);
1881 /* For a positive step, when to < from, exit, otherwise compute
1882 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
1883 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
1884 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
1885 fold_build2_loc (loc, MINUS_EXPR, utype,
1886 tou, fromu),
1887 stepu);
1888 pos = build2 (COMPOUND_EXPR, void_type_node,
1889 fold_build2 (MODIFY_EXPR, void_type_node,
1890 countm1, tmp2),
1891 build3_loc (loc, COND_EXPR, void_type_node, tmp,
1892 build1_loc (loc, GOTO_EXPR, void_type_node,
1893 exit_label), NULL_TREE));
1895 /* For a negative step, when to > from, exit, otherwise compute
1896 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
1897 tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, to, from);
1898 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
1899 fold_build2_loc (loc, MINUS_EXPR, utype,
1900 fromu, tou),
1901 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
1902 neg = build2 (COMPOUND_EXPR, void_type_node,
1903 fold_build2 (MODIFY_EXPR, void_type_node,
1904 countm1, tmp2),
1905 build3_loc (loc, COND_EXPR, void_type_node, tmp,
1906 build1_loc (loc, GOTO_EXPR, void_type_node,
1907 exit_label), NULL_TREE));
1909 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
1910 build_int_cst (TREE_TYPE (step), 0));
1911 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
1913 gfc_add_expr_to_block (&block, tmp);
1915 else
1917 tree pos_step;
1919 /* TODO: We could use the same width as the real type.
1920 This would probably cause more problems that it solves
1921 when we implement "long double" types. */
1923 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
1924 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
1925 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
1926 gfc_add_modify (&block, countm1, tmp);
1928 /* We need a special check for empty loops:
1929 empty = (step > 0 ? to < from : to > from); */
1930 pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
1931 build_zero_cst (type));
1932 tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
1933 fold_build2_loc (loc, LT_EXPR,
1934 boolean_type_node, to, from),
1935 fold_build2_loc (loc, GT_EXPR,
1936 boolean_type_node, to, from));
1937 /* If the loop is empty, go directly to the exit label. */
1938 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
1939 build1_v (GOTO_EXPR, exit_label),
1940 build_empty_stmt (input_location));
1941 gfc_add_expr_to_block (&block, tmp);
1944 /* Loop body. */
1945 gfc_start_block (&body);
1947 /* Main loop body. */
1948 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1949 gfc_add_expr_to_block (&body, tmp);
1951 /* Label for cycle statements (if needed). */
1952 if (TREE_USED (cycle_label))
1954 tmp = build1_v (LABEL_EXPR, cycle_label);
1955 gfc_add_expr_to_block (&body, tmp);
1958 /* Check whether someone has modified the loop variable. */
1959 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1961 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
1962 saved_dovar);
1963 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1964 "Loop variable has been modified");
1967 /* Exit the loop if there is an I/O result condition or error. */
1968 if (exit_cond)
1970 tmp = build1_v (GOTO_EXPR, exit_label);
1971 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1972 exit_cond, tmp,
1973 build_empty_stmt (input_location));
1974 gfc_add_expr_to_block (&body, tmp);
1977 /* Increment the loop variable. */
1978 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1979 gfc_add_modify_loc (loc, &body, dovar, tmp);
1981 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1982 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1984 /* Initialize countm1t. */
1985 tree countm1t = gfc_create_var (utype, "countm1t");
1986 gfc_add_modify_loc (loc, &body, countm1t, countm1);
1988 /* Decrement the loop count. */
1989 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
1990 build_int_cst (utype, 1));
1991 gfc_add_modify_loc (loc, &body, countm1, tmp);
1993 /* End with the loop condition. Loop until countm1t == 0. */
1994 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, countm1t,
1995 build_int_cst (utype, 0));
1996 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1997 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1998 cond, tmp, build_empty_stmt (loc));
1999 gfc_add_expr_to_block (&body, tmp);
2001 /* End of loop body. */
2002 tmp = gfc_finish_block (&body);
2004 /* The for loop itself. */
2005 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2006 gfc_add_expr_to_block (&block, tmp);
2008 /* Add the exit label. */
2009 tmp = build1_v (LABEL_EXPR, exit_label);
2010 gfc_add_expr_to_block (&block, tmp);
2012 return gfc_finish_block (&block);
2016 /* Translate the DO WHILE construct.
2018 We translate
2020 DO WHILE (cond)
2021 body
2022 END DO
2026 for ( ; ; )
2028 pre_cond;
2029 if (! cond) goto exit_label;
2030 body;
2031 cycle_label:
2033 exit_label:
2035 Because the evaluation of the exit condition `cond' may have side
2036 effects, we can't do much for empty loop bodies. The backend optimizers
2037 should be smart enough to eliminate any dead loops. */
2039 tree
2040 gfc_trans_do_while (gfc_code * code)
2042 gfc_se cond;
2043 tree tmp;
2044 tree cycle_label;
2045 tree exit_label;
2046 stmtblock_t block;
2048 /* Everything we build here is part of the loop body. */
2049 gfc_start_block (&block);
2051 /* Cycle and exit statements are implemented with gotos. */
2052 cycle_label = gfc_build_label_decl (NULL_TREE);
2053 exit_label = gfc_build_label_decl (NULL_TREE);
2055 /* Put the labels where they can be found later. See gfc_trans_do(). */
2056 code->cycle_label = cycle_label;
2057 code->exit_label = exit_label;
2059 /* Create a GIMPLE version of the exit condition. */
2060 gfc_init_se (&cond, NULL);
2061 gfc_conv_expr_val (&cond, code->expr1);
2062 gfc_add_block_to_block (&block, &cond.pre);
2063 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2064 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2066 /* Build "IF (! cond) GOTO exit_label". */
2067 tmp = build1_v (GOTO_EXPR, exit_label);
2068 TREE_USED (exit_label) = 1;
2069 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2070 void_type_node, cond.expr, tmp,
2071 build_empty_stmt (code->expr1->where.lb->location));
2072 gfc_add_expr_to_block (&block, tmp);
2074 /* The main body of the loop. */
2075 tmp = gfc_trans_code (code->block->next);
2076 gfc_add_expr_to_block (&block, tmp);
2078 /* Label for cycle statements (if needed). */
2079 if (TREE_USED (cycle_label))
2081 tmp = build1_v (LABEL_EXPR, cycle_label);
2082 gfc_add_expr_to_block (&block, tmp);
2085 /* End of loop body. */
2086 tmp = gfc_finish_block (&block);
2088 gfc_init_block (&block);
2089 /* Build the loop. */
2090 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2091 void_type_node, tmp);
2092 gfc_add_expr_to_block (&block, tmp);
2094 /* Add the exit label. */
2095 tmp = build1_v (LABEL_EXPR, exit_label);
2096 gfc_add_expr_to_block (&block, tmp);
2098 return gfc_finish_block (&block);
2102 /* Translate the SELECT CASE construct for INTEGER case expressions,
2103 without killing all potential optimizations. The problem is that
2104 Fortran allows unbounded cases, but the back-end does not, so we
2105 need to intercept those before we enter the equivalent SWITCH_EXPR
2106 we can build.
2108 For example, we translate this,
2110 SELECT CASE (expr)
2111 CASE (:100,101,105:115)
2112 block_1
2113 CASE (190:199,200:)
2114 block_2
2115 CASE (300)
2116 block_3
2117 CASE DEFAULT
2118 block_4
2119 END SELECT
2121 to the GENERIC equivalent,
2123 switch (expr)
2125 case (minimum value for typeof(expr) ... 100:
2126 case 101:
2127 case 105 ... 114:
2128 block1:
2129 goto end_label;
2131 case 200 ... (maximum value for typeof(expr):
2132 case 190 ... 199:
2133 block2;
2134 goto end_label;
2136 case 300:
2137 block_3;
2138 goto end_label;
2140 default:
2141 block_4;
2142 goto end_label;
2145 end_label: */
2147 static tree
2148 gfc_trans_integer_select (gfc_code * code)
2150 gfc_code *c;
2151 gfc_case *cp;
2152 tree end_label;
2153 tree tmp;
2154 gfc_se se;
2155 stmtblock_t block;
2156 stmtblock_t body;
2158 gfc_start_block (&block);
2160 /* Calculate the switch expression. */
2161 gfc_init_se (&se, NULL);
2162 gfc_conv_expr_val (&se, code->expr1);
2163 gfc_add_block_to_block (&block, &se.pre);
2165 end_label = gfc_build_label_decl (NULL_TREE);
2167 gfc_init_block (&body);
2169 for (c = code->block; c; c = c->block)
2171 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2173 tree low, high;
2174 tree label;
2176 /* Assume it's the default case. */
2177 low = high = NULL_TREE;
2179 if (cp->low)
2181 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2182 cp->low->ts.kind);
2184 /* If there's only a lower bound, set the high bound to the
2185 maximum value of the case expression. */
2186 if (!cp->high)
2187 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2190 if (cp->high)
2192 /* Three cases are possible here:
2194 1) There is no lower bound, e.g. CASE (:N).
2195 2) There is a lower bound .NE. high bound, that is
2196 a case range, e.g. CASE (N:M) where M>N (we make
2197 sure that M>N during type resolution).
2198 3) There is a lower bound, and it has the same value
2199 as the high bound, e.g. CASE (N:N). This is our
2200 internal representation of CASE(N).
2202 In the first and second case, we need to set a value for
2203 high. In the third case, we don't because the GCC middle
2204 end represents a single case value by just letting high be
2205 a NULL_TREE. We can't do that because we need to be able
2206 to represent unbounded cases. */
2208 if (!cp->low
2209 || (cp->low
2210 && mpz_cmp (cp->low->value.integer,
2211 cp->high->value.integer) != 0))
2212 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2213 cp->high->ts.kind);
2215 /* Unbounded case. */
2216 if (!cp->low)
2217 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2220 /* Build a label. */
2221 label = gfc_build_label_decl (NULL_TREE);
2223 /* Add this case label.
2224 Add parameter 'label', make it match GCC backend. */
2225 tmp = build_case_label (low, high, label);
2226 gfc_add_expr_to_block (&body, tmp);
2229 /* Add the statements for this case. */
2230 tmp = gfc_trans_code (c->next);
2231 gfc_add_expr_to_block (&body, tmp);
2233 /* Break to the end of the construct. */
2234 tmp = build1_v (GOTO_EXPR, end_label);
2235 gfc_add_expr_to_block (&body, tmp);
2238 tmp = gfc_finish_block (&body);
2239 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2240 se.expr, tmp, NULL_TREE);
2241 gfc_add_expr_to_block (&block, tmp);
2243 tmp = build1_v (LABEL_EXPR, end_label);
2244 gfc_add_expr_to_block (&block, tmp);
2246 return gfc_finish_block (&block);
2250 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2252 There are only two cases possible here, even though the standard
2253 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2254 .FALSE., and DEFAULT.
2256 We never generate more than two blocks here. Instead, we always
2257 try to eliminate the DEFAULT case. This way, we can translate this
2258 kind of SELECT construct to a simple
2260 if {} else {};
2262 expression in GENERIC. */
2264 static tree
2265 gfc_trans_logical_select (gfc_code * code)
2267 gfc_code *c;
2268 gfc_code *t, *f, *d;
2269 gfc_case *cp;
2270 gfc_se se;
2271 stmtblock_t block;
2273 /* Assume we don't have any cases at all. */
2274 t = f = d = NULL;
2276 /* Now see which ones we actually do have. We can have at most two
2277 cases in a single case list: one for .TRUE. and one for .FALSE.
2278 The default case is always separate. If the cases for .TRUE. and
2279 .FALSE. are in the same case list, the block for that case list
2280 always executed, and we don't generate code a COND_EXPR. */
2281 for (c = code->block; c; c = c->block)
2283 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2285 if (cp->low)
2287 if (cp->low->value.logical == 0) /* .FALSE. */
2288 f = c;
2289 else /* if (cp->value.logical != 0), thus .TRUE. */
2290 t = c;
2292 else
2293 d = c;
2297 /* Start a new block. */
2298 gfc_start_block (&block);
2300 /* Calculate the switch expression. We always need to do this
2301 because it may have side effects. */
2302 gfc_init_se (&se, NULL);
2303 gfc_conv_expr_val (&se, code->expr1);
2304 gfc_add_block_to_block (&block, &se.pre);
2306 if (t == f && t != NULL)
2308 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2309 translate the code for these cases, append it to the current
2310 block. */
2311 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2313 else
2315 tree true_tree, false_tree, stmt;
2317 true_tree = build_empty_stmt (input_location);
2318 false_tree = build_empty_stmt (input_location);
2320 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2321 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2322 make the missing case the default case. */
2323 if (t != NULL && f != NULL)
2324 d = NULL;
2325 else if (d != NULL)
2327 if (t == NULL)
2328 t = d;
2329 else
2330 f = d;
2333 /* Translate the code for each of these blocks, and append it to
2334 the current block. */
2335 if (t != NULL)
2336 true_tree = gfc_trans_code (t->next);
2338 if (f != NULL)
2339 false_tree = gfc_trans_code (f->next);
2341 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2342 se.expr, true_tree, false_tree);
2343 gfc_add_expr_to_block (&block, stmt);
2346 return gfc_finish_block (&block);
2350 /* The jump table types are stored in static variables to avoid
2351 constructing them from scratch every single time. */
2352 static GTY(()) tree select_struct[2];
2354 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2355 Instead of generating compares and jumps, it is far simpler to
2356 generate a data structure describing the cases in order and call a
2357 library subroutine that locates the right case.
2358 This is particularly true because this is the only case where we
2359 might have to dispose of a temporary.
2360 The library subroutine returns a pointer to jump to or NULL if no
2361 branches are to be taken. */
2363 static tree
2364 gfc_trans_character_select (gfc_code *code)
2366 tree init, end_label, tmp, type, case_num, label, fndecl;
2367 stmtblock_t block, body;
2368 gfc_case *cp, *d;
2369 gfc_code *c;
2370 gfc_se se, expr1se;
2371 int n, k;
2372 vec<constructor_elt, va_gc> *inits = NULL;
2374 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2376 /* The jump table types are stored in static variables to avoid
2377 constructing them from scratch every single time. */
2378 static tree ss_string1[2], ss_string1_len[2];
2379 static tree ss_string2[2], ss_string2_len[2];
2380 static tree ss_target[2];
2382 cp = code->block->ext.block.case_list;
2383 while (cp->left != NULL)
2384 cp = cp->left;
2386 /* Generate the body */
2387 gfc_start_block (&block);
2388 gfc_init_se (&expr1se, NULL);
2389 gfc_conv_expr_reference (&expr1se, code->expr1);
2391 gfc_add_block_to_block (&block, &expr1se.pre);
2393 end_label = gfc_build_label_decl (NULL_TREE);
2395 gfc_init_block (&body);
2397 /* Attempt to optimize length 1 selects. */
2398 if (integer_onep (expr1se.string_length))
2400 for (d = cp; d; d = d->right)
2402 int i;
2403 if (d->low)
2405 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2406 && d->low->ts.type == BT_CHARACTER);
2407 if (d->low->value.character.length > 1)
2409 for (i = 1; i < d->low->value.character.length; i++)
2410 if (d->low->value.character.string[i] != ' ')
2411 break;
2412 if (i != d->low->value.character.length)
2414 if (optimize && d->high && i == 1)
2416 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2417 && d->high->ts.type == BT_CHARACTER);
2418 if (d->high->value.character.length > 1
2419 && (d->low->value.character.string[0]
2420 == d->high->value.character.string[0])
2421 && d->high->value.character.string[1] != ' '
2422 && ((d->low->value.character.string[1] < ' ')
2423 == (d->high->value.character.string[1]
2424 < ' ')))
2425 continue;
2427 break;
2431 if (d->high)
2433 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2434 && d->high->ts.type == BT_CHARACTER);
2435 if (d->high->value.character.length > 1)
2437 for (i = 1; i < d->high->value.character.length; i++)
2438 if (d->high->value.character.string[i] != ' ')
2439 break;
2440 if (i != d->high->value.character.length)
2441 break;
2445 if (d == NULL)
2447 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2449 for (c = code->block; c; c = c->block)
2451 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2453 tree low, high;
2454 tree label;
2455 gfc_char_t r;
2457 /* Assume it's the default case. */
2458 low = high = NULL_TREE;
2460 if (cp->low)
2462 /* CASE ('ab') or CASE ('ab':'az') will never match
2463 any length 1 character. */
2464 if (cp->low->value.character.length > 1
2465 && cp->low->value.character.string[1] != ' ')
2466 continue;
2468 if (cp->low->value.character.length > 0)
2469 r = cp->low->value.character.string[0];
2470 else
2471 r = ' ';
2472 low = build_int_cst (ctype, r);
2474 /* If there's only a lower bound, set the high bound
2475 to the maximum value of the case expression. */
2476 if (!cp->high)
2477 high = TYPE_MAX_VALUE (ctype);
2480 if (cp->high)
2482 if (!cp->low
2483 || (cp->low->value.character.string[0]
2484 != cp->high->value.character.string[0]))
2486 if (cp->high->value.character.length > 0)
2487 r = cp->high->value.character.string[0];
2488 else
2489 r = ' ';
2490 high = build_int_cst (ctype, r);
2493 /* Unbounded case. */
2494 if (!cp->low)
2495 low = TYPE_MIN_VALUE (ctype);
2498 /* Build a label. */
2499 label = gfc_build_label_decl (NULL_TREE);
2501 /* Add this case label.
2502 Add parameter 'label', make it match GCC backend. */
2503 tmp = build_case_label (low, high, label);
2504 gfc_add_expr_to_block (&body, tmp);
2507 /* Add the statements for this case. */
2508 tmp = gfc_trans_code (c->next);
2509 gfc_add_expr_to_block (&body, tmp);
2511 /* Break to the end of the construct. */
2512 tmp = build1_v (GOTO_EXPR, end_label);
2513 gfc_add_expr_to_block (&body, tmp);
2516 tmp = gfc_string_to_single_character (expr1se.string_length,
2517 expr1se.expr,
2518 code->expr1->ts.kind);
2519 case_num = gfc_create_var (ctype, "case_num");
2520 gfc_add_modify (&block, case_num, tmp);
2522 gfc_add_block_to_block (&block, &expr1se.post);
2524 tmp = gfc_finish_block (&body);
2525 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2526 case_num, tmp, NULL_TREE);
2527 gfc_add_expr_to_block (&block, tmp);
2529 tmp = build1_v (LABEL_EXPR, end_label);
2530 gfc_add_expr_to_block (&block, tmp);
2532 return gfc_finish_block (&block);
2536 if (code->expr1->ts.kind == 1)
2537 k = 0;
2538 else if (code->expr1->ts.kind == 4)
2539 k = 1;
2540 else
2541 gcc_unreachable ();
2543 if (select_struct[k] == NULL)
2545 tree *chain = NULL;
2546 select_struct[k] = make_node (RECORD_TYPE);
2548 if (code->expr1->ts.kind == 1)
2549 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2550 else if (code->expr1->ts.kind == 4)
2551 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2552 else
2553 gcc_unreachable ();
2555 #undef ADD_FIELD
2556 #define ADD_FIELD(NAME, TYPE) \
2557 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2558 get_identifier (stringize(NAME)), \
2559 TYPE, \
2560 &chain)
2562 ADD_FIELD (string1, pchartype);
2563 ADD_FIELD (string1_len, gfc_charlen_type_node);
2565 ADD_FIELD (string2, pchartype);
2566 ADD_FIELD (string2_len, gfc_charlen_type_node);
2568 ADD_FIELD (target, integer_type_node);
2569 #undef ADD_FIELD
2571 gfc_finish_type (select_struct[k]);
2574 n = 0;
2575 for (d = cp; d; d = d->right)
2576 d->n = n++;
2578 for (c = code->block; c; c = c->block)
2580 for (d = c->ext.block.case_list; d; d = d->next)
2582 label = gfc_build_label_decl (NULL_TREE);
2583 tmp = build_case_label ((d->low == NULL && d->high == NULL)
2584 ? NULL
2585 : build_int_cst (integer_type_node, d->n),
2586 NULL, label);
2587 gfc_add_expr_to_block (&body, tmp);
2590 tmp = gfc_trans_code (c->next);
2591 gfc_add_expr_to_block (&body, tmp);
2593 tmp = build1_v (GOTO_EXPR, end_label);
2594 gfc_add_expr_to_block (&body, tmp);
2597 /* Generate the structure describing the branches */
2598 for (d = cp; d; d = d->right)
2600 vec<constructor_elt, va_gc> *node = NULL;
2602 gfc_init_se (&se, NULL);
2604 if (d->low == NULL)
2606 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2607 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2609 else
2611 gfc_conv_expr_reference (&se, d->low);
2613 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2614 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2617 if (d->high == NULL)
2619 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2620 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2622 else
2624 gfc_init_se (&se, NULL);
2625 gfc_conv_expr_reference (&se, d->high);
2627 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
2628 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
2631 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
2632 build_int_cst (integer_type_node, d->n));
2634 tmp = build_constructor (select_struct[k], node);
2635 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
2638 type = build_array_type (select_struct[k],
2639 build_index_type (size_int (n-1)));
2641 init = build_constructor (type, inits);
2642 TREE_CONSTANT (init) = 1;
2643 TREE_STATIC (init) = 1;
2644 /* Create a static variable to hold the jump table. */
2645 tmp = gfc_create_var (type, "jumptable");
2646 TREE_CONSTANT (tmp) = 1;
2647 TREE_STATIC (tmp) = 1;
2648 TREE_READONLY (tmp) = 1;
2649 DECL_INITIAL (tmp) = init;
2650 init = tmp;
2652 /* Build the library call */
2653 init = gfc_build_addr_expr (pvoid_type_node, init);
2655 if (code->expr1->ts.kind == 1)
2656 fndecl = gfor_fndecl_select_string;
2657 else if (code->expr1->ts.kind == 4)
2658 fndecl = gfor_fndecl_select_string_char4;
2659 else
2660 gcc_unreachable ();
2662 tmp = build_call_expr_loc (input_location,
2663 fndecl, 4, init,
2664 build_int_cst (gfc_charlen_type_node, n),
2665 expr1se.expr, expr1se.string_length);
2666 case_num = gfc_create_var (integer_type_node, "case_num");
2667 gfc_add_modify (&block, case_num, tmp);
2669 gfc_add_block_to_block (&block, &expr1se.post);
2671 tmp = gfc_finish_block (&body);
2672 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2673 case_num, tmp, NULL_TREE);
2674 gfc_add_expr_to_block (&block, tmp);
2676 tmp = build1_v (LABEL_EXPR, end_label);
2677 gfc_add_expr_to_block (&block, tmp);
2679 return gfc_finish_block (&block);
2683 /* Translate the three variants of the SELECT CASE construct.
2685 SELECT CASEs with INTEGER case expressions can be translated to an
2686 equivalent GENERIC switch statement, and for LOGICAL case
2687 expressions we build one or two if-else compares.
2689 SELECT CASEs with CHARACTER case expressions are a whole different
2690 story, because they don't exist in GENERIC. So we sort them and
2691 do a binary search at runtime.
2693 Fortran has no BREAK statement, and it does not allow jumps from
2694 one case block to another. That makes things a lot easier for
2695 the optimizers. */
2697 tree
2698 gfc_trans_select (gfc_code * code)
2700 stmtblock_t block;
2701 tree body;
2702 tree exit_label;
2704 gcc_assert (code && code->expr1);
2705 gfc_init_block (&block);
2707 /* Build the exit label and hang it in. */
2708 exit_label = gfc_build_label_decl (NULL_TREE);
2709 code->exit_label = exit_label;
2711 /* Empty SELECT constructs are legal. */
2712 if (code->block == NULL)
2713 body = build_empty_stmt (input_location);
2715 /* Select the correct translation function. */
2716 else
2717 switch (code->expr1->ts.type)
2719 case BT_LOGICAL:
2720 body = gfc_trans_logical_select (code);
2721 break;
2723 case BT_INTEGER:
2724 body = gfc_trans_integer_select (code);
2725 break;
2727 case BT_CHARACTER:
2728 body = gfc_trans_character_select (code);
2729 break;
2731 default:
2732 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
2733 /* Not reached */
2736 /* Build everything together. */
2737 gfc_add_expr_to_block (&block, body);
2738 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
2740 return gfc_finish_block (&block);
2744 /* Traversal function to substitute a replacement symtree if the symbol
2745 in the expression is the same as that passed. f == 2 signals that
2746 that variable itself is not to be checked - only the references.
2747 This group of functions is used when the variable expression in a
2748 FORALL assignment has internal references. For example:
2749 FORALL (i = 1:4) p(p(i)) = i
2750 The only recourse here is to store a copy of 'p' for the index
2751 expression. */
2753 static gfc_symtree *new_symtree;
2754 static gfc_symtree *old_symtree;
2756 static bool
2757 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
2759 if (expr->expr_type != EXPR_VARIABLE)
2760 return false;
2762 if (*f == 2)
2763 *f = 1;
2764 else if (expr->symtree->n.sym == sym)
2765 expr->symtree = new_symtree;
2767 return false;
2770 static void
2771 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
2773 gfc_traverse_expr (e, sym, forall_replace, f);
2776 static bool
2777 forall_restore (gfc_expr *expr,
2778 gfc_symbol *sym ATTRIBUTE_UNUSED,
2779 int *f ATTRIBUTE_UNUSED)
2781 if (expr->expr_type != EXPR_VARIABLE)
2782 return false;
2784 if (expr->symtree == new_symtree)
2785 expr->symtree = old_symtree;
2787 return false;
2790 static void
2791 forall_restore_symtree (gfc_expr *e)
2793 gfc_traverse_expr (e, NULL, forall_restore, 0);
2796 static void
2797 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
2799 gfc_se tse;
2800 gfc_se rse;
2801 gfc_expr *e;
2802 gfc_symbol *new_sym;
2803 gfc_symbol *old_sym;
2804 gfc_symtree *root;
2805 tree tmp;
2807 /* Build a copy of the lvalue. */
2808 old_symtree = c->expr1->symtree;
2809 old_sym = old_symtree->n.sym;
2810 e = gfc_lval_expr_from_sym (old_sym);
2811 if (old_sym->attr.dimension)
2813 gfc_init_se (&tse, NULL);
2814 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
2815 gfc_add_block_to_block (pre, &tse.pre);
2816 gfc_add_block_to_block (post, &tse.post);
2817 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
2819 if (e->ts.type != BT_CHARACTER)
2821 /* Use the variable offset for the temporary. */
2822 tmp = gfc_conv_array_offset (old_sym->backend_decl);
2823 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
2826 else
2828 gfc_init_se (&tse, NULL);
2829 gfc_init_se (&rse, NULL);
2830 gfc_conv_expr (&rse, e);
2831 if (e->ts.type == BT_CHARACTER)
2833 tse.string_length = rse.string_length;
2834 tmp = gfc_get_character_type_len (gfc_default_character_kind,
2835 tse.string_length);
2836 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
2837 rse.string_length);
2838 gfc_add_block_to_block (pre, &tse.pre);
2839 gfc_add_block_to_block (post, &tse.post);
2841 else
2843 tmp = gfc_typenode_for_spec (&e->ts);
2844 tse.expr = gfc_create_var (tmp, "temp");
2847 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
2848 e->expr_type == EXPR_VARIABLE, false);
2849 gfc_add_expr_to_block (pre, tmp);
2851 gfc_free_expr (e);
2853 /* Create a new symbol to represent the lvalue. */
2854 new_sym = gfc_new_symbol (old_sym->name, NULL);
2855 new_sym->ts = old_sym->ts;
2856 new_sym->attr.referenced = 1;
2857 new_sym->attr.temporary = 1;
2858 new_sym->attr.dimension = old_sym->attr.dimension;
2859 new_sym->attr.flavor = old_sym->attr.flavor;
2861 /* Use the temporary as the backend_decl. */
2862 new_sym->backend_decl = tse.expr;
2864 /* Create a fake symtree for it. */
2865 root = NULL;
2866 new_symtree = gfc_new_symtree (&root, old_sym->name);
2867 new_symtree->n.sym = new_sym;
2868 gcc_assert (new_symtree == root);
2870 /* Go through the expression reference replacing the old_symtree
2871 with the new. */
2872 forall_replace_symtree (c->expr1, old_sym, 2);
2874 /* Now we have made this temporary, we might as well use it for
2875 the right hand side. */
2876 forall_replace_symtree (c->expr2, old_sym, 1);
2880 /* Handles dependencies in forall assignments. */
2881 static int
2882 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
2884 gfc_ref *lref;
2885 gfc_ref *rref;
2886 int need_temp;
2887 gfc_symbol *lsym;
2889 lsym = c->expr1->symtree->n.sym;
2890 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
2892 /* Now check for dependencies within the 'variable'
2893 expression itself. These are treated by making a complete
2894 copy of variable and changing all the references to it
2895 point to the copy instead. Note that the shallow copy of
2896 the variable will not suffice for derived types with
2897 pointer components. We therefore leave these to their
2898 own devices. */
2899 if (lsym->ts.type == BT_DERIVED
2900 && lsym->ts.u.derived->attr.pointer_comp)
2901 return need_temp;
2903 new_symtree = NULL;
2904 if (find_forall_index (c->expr1, lsym, 2))
2906 forall_make_variable_temp (c, pre, post);
2907 need_temp = 0;
2910 /* Substrings with dependencies are treated in the same
2911 way. */
2912 if (c->expr1->ts.type == BT_CHARACTER
2913 && c->expr1->ref
2914 && c->expr2->expr_type == EXPR_VARIABLE
2915 && lsym == c->expr2->symtree->n.sym)
2917 for (lref = c->expr1->ref; lref; lref = lref->next)
2918 if (lref->type == REF_SUBSTRING)
2919 break;
2920 for (rref = c->expr2->ref; rref; rref = rref->next)
2921 if (rref->type == REF_SUBSTRING)
2922 break;
2924 if (rref && lref
2925 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
2927 forall_make_variable_temp (c, pre, post);
2928 need_temp = 0;
2931 return need_temp;
2935 static void
2936 cleanup_forall_symtrees (gfc_code *c)
2938 forall_restore_symtree (c->expr1);
2939 forall_restore_symtree (c->expr2);
2940 free (new_symtree->n.sym);
2941 free (new_symtree);
2945 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
2946 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
2947 indicates whether we should generate code to test the FORALLs mask
2948 array. OUTER is the loop header to be used for initializing mask
2949 indices.
2951 The generated loop format is:
2952 count = (end - start + step) / step
2953 loopvar = start
2954 while (1)
2956 if (count <=0 )
2957 goto end_of_loop
2958 <body>
2959 loopvar += step
2960 count --
2962 end_of_loop: */
2964 static tree
2965 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
2966 int mask_flag, stmtblock_t *outer)
2968 int n, nvar;
2969 tree tmp;
2970 tree cond;
2971 stmtblock_t block;
2972 tree exit_label;
2973 tree count;
2974 tree var, start, end, step;
2975 iter_info *iter;
2977 /* Initialize the mask index outside the FORALL nest. */
2978 if (mask_flag && forall_tmp->mask)
2979 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
2981 iter = forall_tmp->this_loop;
2982 nvar = forall_tmp->nvar;
2983 for (n = 0; n < nvar; n++)
2985 var = iter->var;
2986 start = iter->start;
2987 end = iter->end;
2988 step = iter->step;
2990 exit_label = gfc_build_label_decl (NULL_TREE);
2991 TREE_USED (exit_label) = 1;
2993 /* The loop counter. */
2994 count = gfc_create_var (TREE_TYPE (var), "count");
2996 /* The body of the loop. */
2997 gfc_init_block (&block);
2999 /* The exit condition. */
3000 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3001 count, build_int_cst (TREE_TYPE (count), 0));
3002 if (forall_tmp->do_concurrent)
3003 cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3004 build_int_cst (integer_type_node,
3005 annot_expr_ivdep_kind));
3007 tmp = build1_v (GOTO_EXPR, exit_label);
3008 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3009 cond, tmp, build_empty_stmt (input_location));
3010 gfc_add_expr_to_block (&block, tmp);
3012 /* The main loop body. */
3013 gfc_add_expr_to_block (&block, body);
3015 /* Increment the loop variable. */
3016 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3017 step);
3018 gfc_add_modify (&block, var, tmp);
3020 /* Advance to the next mask element. Only do this for the
3021 innermost loop. */
3022 if (n == 0 && mask_flag && forall_tmp->mask)
3024 tree maskindex = forall_tmp->maskindex;
3025 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3026 maskindex, gfc_index_one_node);
3027 gfc_add_modify (&block, maskindex, tmp);
3030 /* Decrement the loop counter. */
3031 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3032 build_int_cst (TREE_TYPE (var), 1));
3033 gfc_add_modify (&block, count, tmp);
3035 body = gfc_finish_block (&block);
3037 /* Loop var initialization. */
3038 gfc_init_block (&block);
3039 gfc_add_modify (&block, var, start);
3042 /* Initialize the loop counter. */
3043 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3044 start);
3045 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3046 tmp);
3047 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3048 tmp, step);
3049 gfc_add_modify (&block, count, tmp);
3051 /* The loop expression. */
3052 tmp = build1_v (LOOP_EXPR, body);
3053 gfc_add_expr_to_block (&block, tmp);
3055 /* The exit label. */
3056 tmp = build1_v (LABEL_EXPR, exit_label);
3057 gfc_add_expr_to_block (&block, tmp);
3059 body = gfc_finish_block (&block);
3060 iter = iter->next;
3062 return body;
3066 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3067 is nonzero, the body is controlled by all masks in the forall nest.
3068 Otherwise, the innermost loop is not controlled by it's mask. This
3069 is used for initializing that mask. */
3071 static tree
3072 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3073 int mask_flag)
3075 tree tmp;
3076 stmtblock_t header;
3077 forall_info *forall_tmp;
3078 tree mask, maskindex;
3080 gfc_start_block (&header);
3082 forall_tmp = nested_forall_info;
3083 while (forall_tmp != NULL)
3085 /* Generate body with masks' control. */
3086 if (mask_flag)
3088 mask = forall_tmp->mask;
3089 maskindex = forall_tmp->maskindex;
3091 /* If a mask was specified make the assignment conditional. */
3092 if (mask)
3094 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3095 body = build3_v (COND_EXPR, tmp, body,
3096 build_empty_stmt (input_location));
3099 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3100 forall_tmp = forall_tmp->prev_nest;
3101 mask_flag = 1;
3104 gfc_add_expr_to_block (&header, body);
3105 return gfc_finish_block (&header);
3109 /* Allocate data for holding a temporary array. Returns either a local
3110 temporary array or a pointer variable. */
3112 static tree
3113 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3114 tree elem_type)
3116 tree tmpvar;
3117 tree type;
3118 tree tmp;
3120 if (INTEGER_CST_P (size))
3121 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3122 size, gfc_index_one_node);
3123 else
3124 tmp = NULL_TREE;
3126 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3127 type = build_array_type (elem_type, type);
3128 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3130 tmpvar = gfc_create_var (type, "temp");
3131 *pdata = NULL_TREE;
3133 else
3135 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3136 *pdata = convert (pvoid_type_node, tmpvar);
3138 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3139 gfc_add_modify (pblock, tmpvar, tmp);
3141 return tmpvar;
3145 /* Generate codes to copy the temporary to the actual lhs. */
3147 static tree
3148 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3149 tree count1, tree wheremask, bool invert)
3151 gfc_ss *lss;
3152 gfc_se lse, rse;
3153 stmtblock_t block, body;
3154 gfc_loopinfo loop1;
3155 tree tmp;
3156 tree wheremaskexpr;
3158 /* Walk the lhs. */
3159 lss = gfc_walk_expr (expr);
3161 if (lss == gfc_ss_terminator)
3163 gfc_start_block (&block);
3165 gfc_init_se (&lse, NULL);
3167 /* Translate the expression. */
3168 gfc_conv_expr (&lse, expr);
3170 /* Form the expression for the temporary. */
3171 tmp = gfc_build_array_ref (tmp1, count1, NULL);
3173 /* Use the scalar assignment as is. */
3174 gfc_add_block_to_block (&block, &lse.pre);
3175 gfc_add_modify (&block, lse.expr, tmp);
3176 gfc_add_block_to_block (&block, &lse.post);
3178 /* Increment the count1. */
3179 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3180 count1, gfc_index_one_node);
3181 gfc_add_modify (&block, count1, tmp);
3183 tmp = gfc_finish_block (&block);
3185 else
3187 gfc_start_block (&block);
3189 gfc_init_loopinfo (&loop1);
3190 gfc_init_se (&rse, NULL);
3191 gfc_init_se (&lse, NULL);
3193 /* Associate the lss with the loop. */
3194 gfc_add_ss_to_loop (&loop1, lss);
3196 /* Calculate the bounds of the scalarization. */
3197 gfc_conv_ss_startstride (&loop1);
3198 /* Setup the scalarizing loops. */
3199 gfc_conv_loop_setup (&loop1, &expr->where);
3201 gfc_mark_ss_chain_used (lss, 1);
3203 /* Start the scalarized loop body. */
3204 gfc_start_scalarized_body (&loop1, &body);
3206 /* Setup the gfc_se structures. */
3207 gfc_copy_loopinfo_to_se (&lse, &loop1);
3208 lse.ss = lss;
3210 /* Form the expression of the temporary. */
3211 if (lss != gfc_ss_terminator)
3212 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3213 /* Translate expr. */
3214 gfc_conv_expr (&lse, expr);
3216 /* Use the scalar assignment. */
3217 rse.string_length = lse.string_length;
3218 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, true);
3220 /* Form the mask expression according to the mask tree list. */
3221 if (wheremask)
3223 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3224 if (invert)
3225 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3226 TREE_TYPE (wheremaskexpr),
3227 wheremaskexpr);
3228 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3229 wheremaskexpr, tmp,
3230 build_empty_stmt (input_location));
3233 gfc_add_expr_to_block (&body, tmp);
3235 /* Increment count1. */
3236 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3237 count1, gfc_index_one_node);
3238 gfc_add_modify (&body, count1, tmp);
3240 /* Increment count3. */
3241 if (count3)
3243 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3244 gfc_array_index_type, count3,
3245 gfc_index_one_node);
3246 gfc_add_modify (&body, count3, tmp);
3249 /* Generate the copying loops. */
3250 gfc_trans_scalarizing_loops (&loop1, &body);
3251 gfc_add_block_to_block (&block, &loop1.pre);
3252 gfc_add_block_to_block (&block, &loop1.post);
3253 gfc_cleanup_loop (&loop1);
3255 tmp = gfc_finish_block (&block);
3257 return tmp;
3261 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3262 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3263 and should not be freed. WHEREMASK is the conditional execution mask
3264 whose sense may be inverted by INVERT. */
3266 static tree
3267 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3268 tree count1, gfc_ss *lss, gfc_ss *rss,
3269 tree wheremask, bool invert)
3271 stmtblock_t block, body1;
3272 gfc_loopinfo loop;
3273 gfc_se lse;
3274 gfc_se rse;
3275 tree tmp;
3276 tree wheremaskexpr;
3278 gfc_start_block (&block);
3280 gfc_init_se (&rse, NULL);
3281 gfc_init_se (&lse, NULL);
3283 if (lss == gfc_ss_terminator)
3285 gfc_init_block (&body1);
3286 gfc_conv_expr (&rse, expr2);
3287 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3289 else
3291 /* Initialize the loop. */
3292 gfc_init_loopinfo (&loop);
3294 /* We may need LSS to determine the shape of the expression. */
3295 gfc_add_ss_to_loop (&loop, lss);
3296 gfc_add_ss_to_loop (&loop, rss);
3298 gfc_conv_ss_startstride (&loop);
3299 gfc_conv_loop_setup (&loop, &expr2->where);
3301 gfc_mark_ss_chain_used (rss, 1);
3302 /* Start the loop body. */
3303 gfc_start_scalarized_body (&loop, &body1);
3305 /* Translate the expression. */
3306 gfc_copy_loopinfo_to_se (&rse, &loop);
3307 rse.ss = rss;
3308 gfc_conv_expr (&rse, expr2);
3310 /* Form the expression of the temporary. */
3311 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3314 /* Use the scalar assignment. */
3315 lse.string_length = rse.string_length;
3316 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3317 expr2->expr_type == EXPR_VARIABLE, false);
3319 /* Form the mask expression according to the mask tree list. */
3320 if (wheremask)
3322 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3323 if (invert)
3324 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3325 TREE_TYPE (wheremaskexpr),
3326 wheremaskexpr);
3327 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3328 wheremaskexpr, tmp,
3329 build_empty_stmt (input_location));
3332 gfc_add_expr_to_block (&body1, tmp);
3334 if (lss == gfc_ss_terminator)
3336 gfc_add_block_to_block (&block, &body1);
3338 /* Increment count1. */
3339 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3340 count1, gfc_index_one_node);
3341 gfc_add_modify (&block, count1, tmp);
3343 else
3345 /* Increment count1. */
3346 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3347 count1, gfc_index_one_node);
3348 gfc_add_modify (&body1, count1, tmp);
3350 /* Increment count3. */
3351 if (count3)
3353 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3354 gfc_array_index_type,
3355 count3, gfc_index_one_node);
3356 gfc_add_modify (&body1, count3, tmp);
3359 /* Generate the copying loops. */
3360 gfc_trans_scalarizing_loops (&loop, &body1);
3362 gfc_add_block_to_block (&block, &loop.pre);
3363 gfc_add_block_to_block (&block, &loop.post);
3365 gfc_cleanup_loop (&loop);
3366 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3367 as tree nodes in SS may not be valid in different scope. */
3370 tmp = gfc_finish_block (&block);
3371 return tmp;
3375 /* Calculate the size of temporary needed in the assignment inside forall.
3376 LSS and RSS are filled in this function. */
3378 static tree
3379 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3380 stmtblock_t * pblock,
3381 gfc_ss **lss, gfc_ss **rss)
3383 gfc_loopinfo loop;
3384 tree size;
3385 int i;
3386 int save_flag;
3387 tree tmp;
3389 *lss = gfc_walk_expr (expr1);
3390 *rss = NULL;
3392 size = gfc_index_one_node;
3393 if (*lss != gfc_ss_terminator)
3395 gfc_init_loopinfo (&loop);
3397 /* Walk the RHS of the expression. */
3398 *rss = gfc_walk_expr (expr2);
3399 if (*rss == gfc_ss_terminator)
3400 /* The rhs is scalar. Add a ss for the expression. */
3401 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3403 /* Associate the SS with the loop. */
3404 gfc_add_ss_to_loop (&loop, *lss);
3405 /* We don't actually need to add the rhs at this point, but it might
3406 make guessing the loop bounds a bit easier. */
3407 gfc_add_ss_to_loop (&loop, *rss);
3409 /* We only want the shape of the expression, not rest of the junk
3410 generated by the scalarizer. */
3411 loop.array_parameter = 1;
3413 /* Calculate the bounds of the scalarization. */
3414 save_flag = gfc_option.rtcheck;
3415 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3416 gfc_conv_ss_startstride (&loop);
3417 gfc_option.rtcheck = save_flag;
3418 gfc_conv_loop_setup (&loop, &expr2->where);
3420 /* Figure out how many elements we need. */
3421 for (i = 0; i < loop.dimen; i++)
3423 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3424 gfc_array_index_type,
3425 gfc_index_one_node, loop.from[i]);
3426 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3427 gfc_array_index_type, tmp, loop.to[i]);
3428 size = fold_build2_loc (input_location, MULT_EXPR,
3429 gfc_array_index_type, size, tmp);
3431 gfc_add_block_to_block (pblock, &loop.pre);
3432 size = gfc_evaluate_now (size, pblock);
3433 gfc_add_block_to_block (pblock, &loop.post);
3435 /* TODO: write a function that cleans up a loopinfo without freeing
3436 the SS chains. Currently a NOP. */
3439 return size;
3443 /* Calculate the overall iterator number of the nested forall construct.
3444 This routine actually calculates the number of times the body of the
3445 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3446 that by the expression INNER_SIZE. The BLOCK argument specifies the
3447 block in which to calculate the result, and the optional INNER_SIZE_BODY
3448 argument contains any statements that need to executed (inside the loop)
3449 to initialize or calculate INNER_SIZE. */
3451 static tree
3452 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3453 stmtblock_t *inner_size_body, stmtblock_t *block)
3455 forall_info *forall_tmp = nested_forall_info;
3456 tree tmp, number;
3457 stmtblock_t body;
3459 /* We can eliminate the innermost unconditional loops with constant
3460 array bounds. */
3461 if (INTEGER_CST_P (inner_size))
3463 while (forall_tmp
3464 && !forall_tmp->mask
3465 && INTEGER_CST_P (forall_tmp->size))
3467 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3468 gfc_array_index_type,
3469 inner_size, forall_tmp->size);
3470 forall_tmp = forall_tmp->prev_nest;
3473 /* If there are no loops left, we have our constant result. */
3474 if (!forall_tmp)
3475 return inner_size;
3478 /* Otherwise, create a temporary variable to compute the result. */
3479 number = gfc_create_var (gfc_array_index_type, "num");
3480 gfc_add_modify (block, number, gfc_index_zero_node);
3482 gfc_start_block (&body);
3483 if (inner_size_body)
3484 gfc_add_block_to_block (&body, inner_size_body);
3485 if (forall_tmp)
3486 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3487 gfc_array_index_type, number, inner_size);
3488 else
3489 tmp = inner_size;
3490 gfc_add_modify (&body, number, tmp);
3491 tmp = gfc_finish_block (&body);
3493 /* Generate loops. */
3494 if (forall_tmp != NULL)
3495 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3497 gfc_add_expr_to_block (block, tmp);
3499 return number;
3503 /* Allocate temporary for forall construct. SIZE is the size of temporary
3504 needed. PTEMP1 is returned for space free. */
3506 static tree
3507 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3508 tree * ptemp1)
3510 tree bytesize;
3511 tree unit;
3512 tree tmp;
3514 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3515 if (!integer_onep (unit))
3516 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3517 gfc_array_index_type, size, unit);
3518 else
3519 bytesize = size;
3521 *ptemp1 = NULL;
3522 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3524 if (*ptemp1)
3525 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3526 return tmp;
3530 /* Allocate temporary for forall construct according to the information in
3531 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3532 assignment inside forall. PTEMP1 is returned for space free. */
3534 static tree
3535 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3536 tree inner_size, stmtblock_t * inner_size_body,
3537 stmtblock_t * block, tree * ptemp1)
3539 tree size;
3541 /* Calculate the total size of temporary needed in forall construct. */
3542 size = compute_overall_iter_number (nested_forall_info, inner_size,
3543 inner_size_body, block);
3545 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3549 /* Handle assignments inside forall which need temporary.
3551 forall (i=start:end:stride; maskexpr)
3552 e<i> = f<i>
3553 end forall
3554 (where e,f<i> are arbitrary expressions possibly involving i
3555 and there is a dependency between e<i> and f<i>)
3556 Translates to:
3557 masktmp(:) = maskexpr(:)
3559 maskindex = 0;
3560 count1 = 0;
3561 num = 0;
3562 for (i = start; i <= end; i += stride)
3563 num += SIZE (f<i>)
3564 count1 = 0;
3565 ALLOCATE (tmp(num))
3566 for (i = start; i <= end; i += stride)
3568 if (masktmp[maskindex++])
3569 tmp[count1++] = f<i>
3571 maskindex = 0;
3572 count1 = 0;
3573 for (i = start; i <= end; i += stride)
3575 if (masktmp[maskindex++])
3576 e<i> = tmp[count1++]
3578 DEALLOCATE (tmp)
3580 static void
3581 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3582 tree wheremask, bool invert,
3583 forall_info * nested_forall_info,
3584 stmtblock_t * block)
3586 tree type;
3587 tree inner_size;
3588 gfc_ss *lss, *rss;
3589 tree count, count1;
3590 tree tmp, tmp1;
3591 tree ptemp1;
3592 stmtblock_t inner_size_body;
3594 /* Create vars. count1 is the current iterator number of the nested
3595 forall. */
3596 count1 = gfc_create_var (gfc_array_index_type, "count1");
3598 /* Count is the wheremask index. */
3599 if (wheremask)
3601 count = gfc_create_var (gfc_array_index_type, "count");
3602 gfc_add_modify (block, count, gfc_index_zero_node);
3604 else
3605 count = NULL;
3607 /* Initialize count1. */
3608 gfc_add_modify (block, count1, gfc_index_zero_node);
3610 /* Calculate the size of temporary needed in the assignment. Return loop, lss
3611 and rss which are used in function generate_loop_for_rhs_to_temp(). */
3612 gfc_init_block (&inner_size_body);
3613 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
3614 &lss, &rss);
3616 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3617 if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->length)
3619 if (!expr1->ts.u.cl->backend_decl)
3621 gfc_se tse;
3622 gfc_init_se (&tse, NULL);
3623 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
3624 expr1->ts.u.cl->backend_decl = tse.expr;
3626 type = gfc_get_character_type_len (gfc_default_character_kind,
3627 expr1->ts.u.cl->backend_decl);
3629 else
3630 type = gfc_typenode_for_spec (&expr1->ts);
3632 /* Allocate temporary for nested forall construct according to the
3633 information in nested_forall_info and inner_size. */
3634 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
3635 &inner_size_body, block, &ptemp1);
3637 /* Generate codes to copy rhs to the temporary . */
3638 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
3639 wheremask, invert);
3641 /* Generate body and loops according to the information in
3642 nested_forall_info. */
3643 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3644 gfc_add_expr_to_block (block, tmp);
3646 /* Reset count1. */
3647 gfc_add_modify (block, count1, gfc_index_zero_node);
3649 /* Reset count. */
3650 if (wheremask)
3651 gfc_add_modify (block, count, gfc_index_zero_node);
3653 /* Generate codes to copy the temporary to lhs. */
3654 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
3655 wheremask, invert);
3657 /* Generate body and loops according to the information in
3658 nested_forall_info. */
3659 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3660 gfc_add_expr_to_block (block, tmp);
3662 if (ptemp1)
3664 /* Free the temporary. */
3665 tmp = gfc_call_free (ptemp1);
3666 gfc_add_expr_to_block (block, tmp);
3671 /* Translate pointer assignment inside FORALL which need temporary. */
3673 static void
3674 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3675 forall_info * nested_forall_info,
3676 stmtblock_t * block)
3678 tree type;
3679 tree inner_size;
3680 gfc_ss *lss, *rss;
3681 gfc_se lse;
3682 gfc_se rse;
3683 gfc_array_info *info;
3684 gfc_loopinfo loop;
3685 tree desc;
3686 tree parm;
3687 tree parmtype;
3688 stmtblock_t body;
3689 tree count;
3690 tree tmp, tmp1, ptemp1;
3692 count = gfc_create_var (gfc_array_index_type, "count");
3693 gfc_add_modify (block, count, gfc_index_zero_node);
3695 inner_size = gfc_index_one_node;
3696 lss = gfc_walk_expr (expr1);
3697 rss = gfc_walk_expr (expr2);
3698 if (lss == gfc_ss_terminator)
3700 type = gfc_typenode_for_spec (&expr1->ts);
3701 type = build_pointer_type (type);
3703 /* Allocate temporary for nested forall construct according to the
3704 information in nested_forall_info and inner_size. */
3705 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
3706 inner_size, NULL, block, &ptemp1);
3707 gfc_start_block (&body);
3708 gfc_init_se (&lse, NULL);
3709 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3710 gfc_init_se (&rse, NULL);
3711 rse.want_pointer = 1;
3712 gfc_conv_expr (&rse, expr2);
3713 gfc_add_block_to_block (&body, &rse.pre);
3714 gfc_add_modify (&body, lse.expr,
3715 fold_convert (TREE_TYPE (lse.expr), rse.expr));
3716 gfc_add_block_to_block (&body, &rse.post);
3718 /* Increment count. */
3719 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3720 count, gfc_index_one_node);
3721 gfc_add_modify (&body, count, tmp);
3723 tmp = gfc_finish_block (&body);
3725 /* Generate body and loops according to the information in
3726 nested_forall_info. */
3727 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3728 gfc_add_expr_to_block (block, tmp);
3730 /* Reset count. */
3731 gfc_add_modify (block, count, gfc_index_zero_node);
3733 gfc_start_block (&body);
3734 gfc_init_se (&lse, NULL);
3735 gfc_init_se (&rse, NULL);
3736 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
3737 lse.want_pointer = 1;
3738 gfc_conv_expr (&lse, expr1);
3739 gfc_add_block_to_block (&body, &lse.pre);
3740 gfc_add_modify (&body, lse.expr, rse.expr);
3741 gfc_add_block_to_block (&body, &lse.post);
3742 /* Increment count. */
3743 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3744 count, gfc_index_one_node);
3745 gfc_add_modify (&body, count, tmp);
3746 tmp = gfc_finish_block (&body);
3748 /* Generate body and loops according to the information in
3749 nested_forall_info. */
3750 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3751 gfc_add_expr_to_block (block, tmp);
3753 else
3755 gfc_init_loopinfo (&loop);
3757 /* Associate the SS with the loop. */
3758 gfc_add_ss_to_loop (&loop, rss);
3760 /* Setup the scalarizing loops and bounds. */
3761 gfc_conv_ss_startstride (&loop);
3763 gfc_conv_loop_setup (&loop, &expr2->where);
3765 info = &rss->info->data.array;
3766 desc = info->descriptor;
3768 /* Make a new descriptor. */
3769 parmtype = gfc_get_element_type (TREE_TYPE (desc));
3770 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
3771 loop.from, loop.to, 1,
3772 GFC_ARRAY_UNKNOWN, true);
3774 /* Allocate temporary for nested forall construct. */
3775 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
3776 inner_size, NULL, block, &ptemp1);
3777 gfc_start_block (&body);
3778 gfc_init_se (&lse, NULL);
3779 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3780 lse.direct_byref = 1;
3781 gfc_conv_expr_descriptor (&lse, expr2);
3783 gfc_add_block_to_block (&body, &lse.pre);
3784 gfc_add_block_to_block (&body, &lse.post);
3786 /* Increment count. */
3787 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3788 count, gfc_index_one_node);
3789 gfc_add_modify (&body, count, tmp);
3791 tmp = gfc_finish_block (&body);
3793 /* Generate body and loops according to the information in
3794 nested_forall_info. */
3795 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3796 gfc_add_expr_to_block (block, tmp);
3798 /* Reset count. */
3799 gfc_add_modify (block, count, gfc_index_zero_node);
3801 parm = gfc_build_array_ref (tmp1, count, NULL);
3802 gfc_init_se (&lse, NULL);
3803 gfc_conv_expr_descriptor (&lse, expr1);
3804 gfc_add_modify (&lse.pre, lse.expr, parm);
3805 gfc_start_block (&body);
3806 gfc_add_block_to_block (&body, &lse.pre);
3807 gfc_add_block_to_block (&body, &lse.post);
3809 /* Increment count. */
3810 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3811 count, gfc_index_one_node);
3812 gfc_add_modify (&body, count, tmp);
3814 tmp = gfc_finish_block (&body);
3816 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3817 gfc_add_expr_to_block (block, tmp);
3819 /* Free the temporary. */
3820 if (ptemp1)
3822 tmp = gfc_call_free (ptemp1);
3823 gfc_add_expr_to_block (block, tmp);
3828 /* FORALL and WHERE statements are really nasty, especially when you nest
3829 them. All the rhs of a forall assignment must be evaluated before the
3830 actual assignments are performed. Presumably this also applies to all the
3831 assignments in an inner where statement. */
3833 /* Generate code for a FORALL statement. Any temporaries are allocated as a
3834 linear array, relying on the fact that we process in the same order in all
3835 loops.
3837 forall (i=start:end:stride; maskexpr)
3838 e<i> = f<i>
3839 g<i> = h<i>
3840 end forall
3841 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
3842 Translates to:
3843 count = ((end + 1 - start) / stride)
3844 masktmp(:) = maskexpr(:)
3846 maskindex = 0;
3847 for (i = start; i <= end; i += stride)
3849 if (masktmp[maskindex++])
3850 e<i> = f<i>
3852 maskindex = 0;
3853 for (i = start; i <= end; i += stride)
3855 if (masktmp[maskindex++])
3856 g<i> = h<i>
3859 Note that this code only works when there are no dependencies.
3860 Forall loop with array assignments and data dependencies are a real pain,
3861 because the size of the temporary cannot always be determined before the
3862 loop is executed. This problem is compounded by the presence of nested
3863 FORALL constructs.
3866 static tree
3867 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
3869 stmtblock_t pre;
3870 stmtblock_t post;
3871 stmtblock_t block;
3872 stmtblock_t body;
3873 tree *var;
3874 tree *start;
3875 tree *end;
3876 tree *step;
3877 gfc_expr **varexpr;
3878 tree tmp;
3879 tree assign;
3880 tree size;
3881 tree maskindex;
3882 tree mask;
3883 tree pmask;
3884 tree cycle_label = NULL_TREE;
3885 int n;
3886 int nvar;
3887 int need_temp;
3888 gfc_forall_iterator *fa;
3889 gfc_se se;
3890 gfc_code *c;
3891 gfc_saved_var *saved_vars;
3892 iter_info *this_forall;
3893 forall_info *info;
3894 bool need_mask;
3896 /* Do nothing if the mask is false. */
3897 if (code->expr1
3898 && code->expr1->expr_type == EXPR_CONSTANT
3899 && !code->expr1->value.logical)
3900 return build_empty_stmt (input_location);
3902 n = 0;
3903 /* Count the FORALL index number. */
3904 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
3905 n++;
3906 nvar = n;
3908 /* Allocate the space for var, start, end, step, varexpr. */
3909 var = XCNEWVEC (tree, nvar);
3910 start = XCNEWVEC (tree, nvar);
3911 end = XCNEWVEC (tree, nvar);
3912 step = XCNEWVEC (tree, nvar);
3913 varexpr = XCNEWVEC (gfc_expr *, nvar);
3914 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
3916 /* Allocate the space for info. */
3917 info = XCNEW (forall_info);
3919 gfc_start_block (&pre);
3920 gfc_init_block (&post);
3921 gfc_init_block (&block);
3923 n = 0;
3924 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
3926 gfc_symbol *sym = fa->var->symtree->n.sym;
3928 /* Allocate space for this_forall. */
3929 this_forall = XCNEW (iter_info);
3931 /* Create a temporary variable for the FORALL index. */
3932 tmp = gfc_typenode_for_spec (&sym->ts);
3933 var[n] = gfc_create_var (tmp, sym->name);
3934 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
3936 /* Record it in this_forall. */
3937 this_forall->var = var[n];
3939 /* Replace the index symbol's backend_decl with the temporary decl. */
3940 sym->backend_decl = var[n];
3942 /* Work out the start, end and stride for the loop. */
3943 gfc_init_se (&se, NULL);
3944 gfc_conv_expr_val (&se, fa->start);
3945 /* Record it in this_forall. */
3946 this_forall->start = se.expr;
3947 gfc_add_block_to_block (&block, &se.pre);
3948 start[n] = se.expr;
3950 gfc_init_se (&se, NULL);
3951 gfc_conv_expr_val (&se, fa->end);
3952 /* Record it in this_forall. */
3953 this_forall->end = se.expr;
3954 gfc_make_safe_expr (&se);
3955 gfc_add_block_to_block (&block, &se.pre);
3956 end[n] = se.expr;
3958 gfc_init_se (&se, NULL);
3959 gfc_conv_expr_val (&se, fa->stride);
3960 /* Record it in this_forall. */
3961 this_forall->step = se.expr;
3962 gfc_make_safe_expr (&se);
3963 gfc_add_block_to_block (&block, &se.pre);
3964 step[n] = se.expr;
3966 /* Set the NEXT field of this_forall to NULL. */
3967 this_forall->next = NULL;
3968 /* Link this_forall to the info construct. */
3969 if (info->this_loop)
3971 iter_info *iter_tmp = info->this_loop;
3972 while (iter_tmp->next != NULL)
3973 iter_tmp = iter_tmp->next;
3974 iter_tmp->next = this_forall;
3976 else
3977 info->this_loop = this_forall;
3979 n++;
3981 nvar = n;
3983 /* Calculate the size needed for the current forall level. */
3984 size = gfc_index_one_node;
3985 for (n = 0; n < nvar; n++)
3987 /* size = (end + step - start) / step. */
3988 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
3989 step[n], start[n]);
3990 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
3991 end[n], tmp);
3992 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
3993 tmp, step[n]);
3994 tmp = convert (gfc_array_index_type, tmp);
3996 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
3997 size, tmp);
4000 /* Record the nvar and size of current forall level. */
4001 info->nvar = nvar;
4002 info->size = size;
4004 if (code->expr1)
4006 /* If the mask is .true., consider the FORALL unconditional. */
4007 if (code->expr1->expr_type == EXPR_CONSTANT
4008 && code->expr1->value.logical)
4009 need_mask = false;
4010 else
4011 need_mask = true;
4013 else
4014 need_mask = false;
4016 /* First we need to allocate the mask. */
4017 if (need_mask)
4019 /* As the mask array can be very big, prefer compact boolean types. */
4020 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4021 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4022 size, NULL, &block, &pmask);
4023 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4025 /* Record them in the info structure. */
4026 info->maskindex = maskindex;
4027 info->mask = mask;
4029 else
4031 /* No mask was specified. */
4032 maskindex = NULL_TREE;
4033 mask = pmask = NULL_TREE;
4036 /* Link the current forall level to nested_forall_info. */
4037 info->prev_nest = nested_forall_info;
4038 nested_forall_info = info;
4040 /* Copy the mask into a temporary variable if required.
4041 For now we assume a mask temporary is needed. */
4042 if (need_mask)
4044 /* As the mask array can be very big, prefer compact boolean types. */
4045 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4047 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4049 /* Start of mask assignment loop body. */
4050 gfc_start_block (&body);
4052 /* Evaluate the mask expression. */
4053 gfc_init_se (&se, NULL);
4054 gfc_conv_expr_val (&se, code->expr1);
4055 gfc_add_block_to_block (&body, &se.pre);
4057 /* Store the mask. */
4058 se.expr = convert (mask_type, se.expr);
4060 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4061 gfc_add_modify (&body, tmp, se.expr);
4063 /* Advance to the next mask element. */
4064 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4065 maskindex, gfc_index_one_node);
4066 gfc_add_modify (&body, maskindex, tmp);
4068 /* Generate the loops. */
4069 tmp = gfc_finish_block (&body);
4070 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4071 gfc_add_expr_to_block (&block, tmp);
4074 if (code->op == EXEC_DO_CONCURRENT)
4076 gfc_init_block (&body);
4077 cycle_label = gfc_build_label_decl (NULL_TREE);
4078 code->cycle_label = cycle_label;
4079 tmp = gfc_trans_code (code->block->next);
4080 gfc_add_expr_to_block (&body, tmp);
4082 if (TREE_USED (cycle_label))
4084 tmp = build1_v (LABEL_EXPR, cycle_label);
4085 gfc_add_expr_to_block (&body, tmp);
4088 tmp = gfc_finish_block (&body);
4089 nested_forall_info->do_concurrent = true;
4090 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4091 gfc_add_expr_to_block (&block, tmp);
4092 goto done;
4095 c = code->block->next;
4097 /* TODO: loop merging in FORALL statements. */
4098 /* Now that we've got a copy of the mask, generate the assignment loops. */
4099 while (c)
4101 switch (c->op)
4103 case EXEC_ASSIGN:
4104 /* A scalar or array assignment. DO the simple check for
4105 lhs to rhs dependencies. These make a temporary for the
4106 rhs and form a second forall block to copy to variable. */
4107 need_temp = check_forall_dependencies(c, &pre, &post);
4109 /* Temporaries due to array assignment data dependencies introduce
4110 no end of problems. */
4111 if (need_temp)
4112 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4113 nested_forall_info, &block);
4114 else
4116 /* Use the normal assignment copying routines. */
4117 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4119 /* Generate body and loops. */
4120 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4121 assign, 1);
4122 gfc_add_expr_to_block (&block, tmp);
4125 /* Cleanup any temporary symtrees that have been made to deal
4126 with dependencies. */
4127 if (new_symtree)
4128 cleanup_forall_symtrees (c);
4130 break;
4132 case EXEC_WHERE:
4133 /* Translate WHERE or WHERE construct nested in FORALL. */
4134 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4135 break;
4137 /* Pointer assignment inside FORALL. */
4138 case EXEC_POINTER_ASSIGN:
4139 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4140 if (need_temp)
4141 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4142 nested_forall_info, &block);
4143 else
4145 /* Use the normal assignment copying routines. */
4146 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4148 /* Generate body and loops. */
4149 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4150 assign, 1);
4151 gfc_add_expr_to_block (&block, tmp);
4153 break;
4155 case EXEC_FORALL:
4156 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4157 gfc_add_expr_to_block (&block, tmp);
4158 break;
4160 /* Explicit subroutine calls are prevented by the frontend but interface
4161 assignments can legitimately produce them. */
4162 case EXEC_ASSIGN_CALL:
4163 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4164 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4165 gfc_add_expr_to_block (&block, tmp);
4166 break;
4168 default:
4169 gcc_unreachable ();
4172 c = c->next;
4175 done:
4176 /* Restore the original index variables. */
4177 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4178 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4180 /* Free the space for var, start, end, step, varexpr. */
4181 free (var);
4182 free (start);
4183 free (end);
4184 free (step);
4185 free (varexpr);
4186 free (saved_vars);
4188 for (this_forall = info->this_loop; this_forall;)
4190 iter_info *next = this_forall->next;
4191 free (this_forall);
4192 this_forall = next;
4195 /* Free the space for this forall_info. */
4196 free (info);
4198 if (pmask)
4200 /* Free the temporary for the mask. */
4201 tmp = gfc_call_free (pmask);
4202 gfc_add_expr_to_block (&block, tmp);
4204 if (maskindex)
4205 pushdecl (maskindex);
4207 gfc_add_block_to_block (&pre, &block);
4208 gfc_add_block_to_block (&pre, &post);
4210 return gfc_finish_block (&pre);
4214 /* Translate the FORALL statement or construct. */
4216 tree gfc_trans_forall (gfc_code * code)
4218 return gfc_trans_forall_1 (code, NULL);
4222 /* Translate the DO CONCURRENT construct. */
4224 tree gfc_trans_do_concurrent (gfc_code * code)
4226 return gfc_trans_forall_1 (code, NULL);
4230 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4231 If the WHERE construct is nested in FORALL, compute the overall temporary
4232 needed by the WHERE mask expression multiplied by the iterator number of
4233 the nested forall.
4234 ME is the WHERE mask expression.
4235 MASK is the current execution mask upon input, whose sense may or may
4236 not be inverted as specified by the INVERT argument.
4237 CMASK is the updated execution mask on output, or NULL if not required.
4238 PMASK is the pending execution mask on output, or NULL if not required.
4239 BLOCK is the block in which to place the condition evaluation loops. */
4241 static void
4242 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4243 tree mask, bool invert, tree cmask, tree pmask,
4244 tree mask_type, stmtblock_t * block)
4246 tree tmp, tmp1;
4247 gfc_ss *lss, *rss;
4248 gfc_loopinfo loop;
4249 stmtblock_t body, body1;
4250 tree count, cond, mtmp;
4251 gfc_se lse, rse;
4253 gfc_init_loopinfo (&loop);
4255 lss = gfc_walk_expr (me);
4256 rss = gfc_walk_expr (me);
4258 /* Variable to index the temporary. */
4259 count = gfc_create_var (gfc_array_index_type, "count");
4260 /* Initialize count. */
4261 gfc_add_modify (block, count, gfc_index_zero_node);
4263 gfc_start_block (&body);
4265 gfc_init_se (&rse, NULL);
4266 gfc_init_se (&lse, NULL);
4268 if (lss == gfc_ss_terminator)
4270 gfc_init_block (&body1);
4272 else
4274 /* Initialize the loop. */
4275 gfc_init_loopinfo (&loop);
4277 /* We may need LSS to determine the shape of the expression. */
4278 gfc_add_ss_to_loop (&loop, lss);
4279 gfc_add_ss_to_loop (&loop, rss);
4281 gfc_conv_ss_startstride (&loop);
4282 gfc_conv_loop_setup (&loop, &me->where);
4284 gfc_mark_ss_chain_used (rss, 1);
4285 /* Start the loop body. */
4286 gfc_start_scalarized_body (&loop, &body1);
4288 /* Translate the expression. */
4289 gfc_copy_loopinfo_to_se (&rse, &loop);
4290 rse.ss = rss;
4291 gfc_conv_expr (&rse, me);
4294 /* Variable to evaluate mask condition. */
4295 cond = gfc_create_var (mask_type, "cond");
4296 if (mask && (cmask || pmask))
4297 mtmp = gfc_create_var (mask_type, "mask");
4298 else mtmp = NULL_TREE;
4300 gfc_add_block_to_block (&body1, &lse.pre);
4301 gfc_add_block_to_block (&body1, &rse.pre);
4303 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4305 if (mask && (cmask || pmask))
4307 tmp = gfc_build_array_ref (mask, count, NULL);
4308 if (invert)
4309 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4310 gfc_add_modify (&body1, mtmp, tmp);
4313 if (cmask)
4315 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4316 tmp = cond;
4317 if (mask)
4318 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4319 mtmp, tmp);
4320 gfc_add_modify (&body1, tmp1, tmp);
4323 if (pmask)
4325 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4326 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4327 if (mask)
4328 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4329 tmp);
4330 gfc_add_modify (&body1, tmp1, tmp);
4333 gfc_add_block_to_block (&body1, &lse.post);
4334 gfc_add_block_to_block (&body1, &rse.post);
4336 if (lss == gfc_ss_terminator)
4338 gfc_add_block_to_block (&body, &body1);
4340 else
4342 /* Increment count. */
4343 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4344 count, gfc_index_one_node);
4345 gfc_add_modify (&body1, count, tmp1);
4347 /* Generate the copying loops. */
4348 gfc_trans_scalarizing_loops (&loop, &body1);
4350 gfc_add_block_to_block (&body, &loop.pre);
4351 gfc_add_block_to_block (&body, &loop.post);
4353 gfc_cleanup_loop (&loop);
4354 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4355 as tree nodes in SS may not be valid in different scope. */
4358 tmp1 = gfc_finish_block (&body);
4359 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4360 if (nested_forall_info != NULL)
4361 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4363 gfc_add_expr_to_block (block, tmp1);
4367 /* Translate an assignment statement in a WHERE statement or construct
4368 statement. The MASK expression is used to control which elements
4369 of EXPR1 shall be assigned. The sense of MASK is specified by
4370 INVERT. */
4372 static tree
4373 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4374 tree mask, bool invert,
4375 tree count1, tree count2,
4376 gfc_code *cnext)
4378 gfc_se lse;
4379 gfc_se rse;
4380 gfc_ss *lss;
4381 gfc_ss *lss_section;
4382 gfc_ss *rss;
4384 gfc_loopinfo loop;
4385 tree tmp;
4386 stmtblock_t block;
4387 stmtblock_t body;
4388 tree index, maskexpr;
4390 /* A defined assignment. */
4391 if (cnext && cnext->resolved_sym)
4392 return gfc_trans_call (cnext, true, mask, count1, invert);
4394 #if 0
4395 /* TODO: handle this special case.
4396 Special case a single function returning an array. */
4397 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4399 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4400 if (tmp)
4401 return tmp;
4403 #endif
4405 /* Assignment of the form lhs = rhs. */
4406 gfc_start_block (&block);
4408 gfc_init_se (&lse, NULL);
4409 gfc_init_se (&rse, NULL);
4411 /* Walk the lhs. */
4412 lss = gfc_walk_expr (expr1);
4413 rss = NULL;
4415 /* In each where-assign-stmt, the mask-expr and the variable being
4416 defined shall be arrays of the same shape. */
4417 gcc_assert (lss != gfc_ss_terminator);
4419 /* The assignment needs scalarization. */
4420 lss_section = lss;
4422 /* Find a non-scalar SS from the lhs. */
4423 while (lss_section != gfc_ss_terminator
4424 && lss_section->info->type != GFC_SS_SECTION)
4425 lss_section = lss_section->next;
4427 gcc_assert (lss_section != gfc_ss_terminator);
4429 /* Initialize the scalarizer. */
4430 gfc_init_loopinfo (&loop);
4432 /* Walk the rhs. */
4433 rss = gfc_walk_expr (expr2);
4434 if (rss == gfc_ss_terminator)
4436 /* The rhs is scalar. Add a ss for the expression. */
4437 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4438 rss->info->where = 1;
4441 /* Associate the SS with the loop. */
4442 gfc_add_ss_to_loop (&loop, lss);
4443 gfc_add_ss_to_loop (&loop, rss);
4445 /* Calculate the bounds of the scalarization. */
4446 gfc_conv_ss_startstride (&loop);
4448 /* Resolve any data dependencies in the statement. */
4449 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4451 /* Setup the scalarizing loops. */
4452 gfc_conv_loop_setup (&loop, &expr2->where);
4454 /* Setup the gfc_se structures. */
4455 gfc_copy_loopinfo_to_se (&lse, &loop);
4456 gfc_copy_loopinfo_to_se (&rse, &loop);
4458 rse.ss = rss;
4459 gfc_mark_ss_chain_used (rss, 1);
4460 if (loop.temp_ss == NULL)
4462 lse.ss = lss;
4463 gfc_mark_ss_chain_used (lss, 1);
4465 else
4467 lse.ss = loop.temp_ss;
4468 gfc_mark_ss_chain_used (lss, 3);
4469 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4472 /* Start the scalarized loop body. */
4473 gfc_start_scalarized_body (&loop, &body);
4475 /* Translate the expression. */
4476 gfc_conv_expr (&rse, expr2);
4477 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4478 gfc_conv_tmp_array_ref (&lse);
4479 else
4480 gfc_conv_expr (&lse, expr1);
4482 /* Form the mask expression according to the mask. */
4483 index = count1;
4484 maskexpr = gfc_build_array_ref (mask, index, NULL);
4485 if (invert)
4486 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4487 TREE_TYPE (maskexpr), maskexpr);
4489 /* Use the scalar assignment as is. */
4490 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4491 false, loop.temp_ss == NULL);
4493 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4495 gfc_add_expr_to_block (&body, tmp);
4497 if (lss == gfc_ss_terminator)
4499 /* Increment count1. */
4500 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4501 count1, gfc_index_one_node);
4502 gfc_add_modify (&body, count1, tmp);
4504 /* Use the scalar assignment as is. */
4505 gfc_add_block_to_block (&block, &body);
4507 else
4509 gcc_assert (lse.ss == gfc_ss_terminator
4510 && rse.ss == gfc_ss_terminator);
4512 if (loop.temp_ss != NULL)
4514 /* Increment count1 before finish the main body of a scalarized
4515 expression. */
4516 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4517 gfc_array_index_type, count1, gfc_index_one_node);
4518 gfc_add_modify (&body, count1, tmp);
4519 gfc_trans_scalarized_loop_boundary (&loop, &body);
4521 /* We need to copy the temporary to the actual lhs. */
4522 gfc_init_se (&lse, NULL);
4523 gfc_init_se (&rse, NULL);
4524 gfc_copy_loopinfo_to_se (&lse, &loop);
4525 gfc_copy_loopinfo_to_se (&rse, &loop);
4527 rse.ss = loop.temp_ss;
4528 lse.ss = lss;
4530 gfc_conv_tmp_array_ref (&rse);
4531 gfc_conv_expr (&lse, expr1);
4533 gcc_assert (lse.ss == gfc_ss_terminator
4534 && rse.ss == gfc_ss_terminator);
4536 /* Form the mask expression according to the mask tree list. */
4537 index = count2;
4538 maskexpr = gfc_build_array_ref (mask, index, NULL);
4539 if (invert)
4540 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4541 TREE_TYPE (maskexpr), maskexpr);
4543 /* Use the scalar assignment as is. */
4544 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
4545 tmp = build3_v (COND_EXPR, maskexpr, tmp,
4546 build_empty_stmt (input_location));
4547 gfc_add_expr_to_block (&body, tmp);
4549 /* Increment count2. */
4550 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4551 gfc_array_index_type, count2,
4552 gfc_index_one_node);
4553 gfc_add_modify (&body, count2, tmp);
4555 else
4557 /* Increment count1. */
4558 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4559 gfc_array_index_type, count1,
4560 gfc_index_one_node);
4561 gfc_add_modify (&body, count1, tmp);
4564 /* Generate the copying loops. */
4565 gfc_trans_scalarizing_loops (&loop, &body);
4567 /* Wrap the whole thing up. */
4568 gfc_add_block_to_block (&block, &loop.pre);
4569 gfc_add_block_to_block (&block, &loop.post);
4570 gfc_cleanup_loop (&loop);
4573 return gfc_finish_block (&block);
4577 /* Translate the WHERE construct or statement.
4578 This function can be called iteratively to translate the nested WHERE
4579 construct or statement.
4580 MASK is the control mask. */
4582 static void
4583 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4584 forall_info * nested_forall_info, stmtblock_t * block)
4586 stmtblock_t inner_size_body;
4587 tree inner_size, size;
4588 gfc_ss *lss, *rss;
4589 tree mask_type;
4590 gfc_expr *expr1;
4591 gfc_expr *expr2;
4592 gfc_code *cblock;
4593 gfc_code *cnext;
4594 tree tmp;
4595 tree cond;
4596 tree count1, count2;
4597 bool need_cmask;
4598 bool need_pmask;
4599 int need_temp;
4600 tree pcmask = NULL_TREE;
4601 tree ppmask = NULL_TREE;
4602 tree cmask = NULL_TREE;
4603 tree pmask = NULL_TREE;
4604 gfc_actual_arglist *arg;
4606 /* the WHERE statement or the WHERE construct statement. */
4607 cblock = code->block;
4609 /* As the mask array can be very big, prefer compact boolean types. */
4610 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4612 /* Determine which temporary masks are needed. */
4613 if (!cblock->block)
4615 /* One clause: No ELSEWHEREs. */
4616 need_cmask = (cblock->next != 0);
4617 need_pmask = false;
4619 else if (cblock->block->block)
4621 /* Three or more clauses: Conditional ELSEWHEREs. */
4622 need_cmask = true;
4623 need_pmask = true;
4625 else if (cblock->next)
4627 /* Two clauses, the first non-empty. */
4628 need_cmask = true;
4629 need_pmask = (mask != NULL_TREE
4630 && cblock->block->next != 0);
4632 else if (!cblock->block->next)
4634 /* Two clauses, both empty. */
4635 need_cmask = false;
4636 need_pmask = false;
4638 /* Two clauses, the first empty, the second non-empty. */
4639 else if (mask)
4641 need_cmask = (cblock->block->expr1 != 0);
4642 need_pmask = true;
4644 else
4646 need_cmask = true;
4647 need_pmask = false;
4650 if (need_cmask || need_pmask)
4652 /* Calculate the size of temporary needed by the mask-expr. */
4653 gfc_init_block (&inner_size_body);
4654 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
4655 &inner_size_body, &lss, &rss);
4657 gfc_free_ss_chain (lss);
4658 gfc_free_ss_chain (rss);
4660 /* Calculate the total size of temporary needed. */
4661 size = compute_overall_iter_number (nested_forall_info, inner_size,
4662 &inner_size_body, block);
4664 /* Check whether the size is negative. */
4665 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, size,
4666 gfc_index_zero_node);
4667 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
4668 cond, gfc_index_zero_node, size);
4669 size = gfc_evaluate_now (size, block);
4671 /* Allocate temporary for WHERE mask if needed. */
4672 if (need_cmask)
4673 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4674 &pcmask);
4676 /* Allocate temporary for !mask if needed. */
4677 if (need_pmask)
4678 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4679 &ppmask);
4682 while (cblock)
4684 /* Each time around this loop, the where clause is conditional
4685 on the value of mask and invert, which are updated at the
4686 bottom of the loop. */
4688 /* Has mask-expr. */
4689 if (cblock->expr1)
4691 /* Ensure that the WHERE mask will be evaluated exactly once.
4692 If there are no statements in this WHERE/ELSEWHERE clause,
4693 then we don't need to update the control mask (cmask).
4694 If this is the last clause of the WHERE construct, then
4695 we don't need to update the pending control mask (pmask). */
4696 if (mask)
4697 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4698 mask, invert,
4699 cblock->next ? cmask : NULL_TREE,
4700 cblock->block ? pmask : NULL_TREE,
4701 mask_type, block);
4702 else
4703 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4704 NULL_TREE, false,
4705 (cblock->next || cblock->block)
4706 ? cmask : NULL_TREE,
4707 NULL_TREE, mask_type, block);
4709 invert = false;
4711 /* It's a final elsewhere-stmt. No mask-expr is present. */
4712 else
4713 cmask = mask;
4715 /* The body of this where clause are controlled by cmask with
4716 sense specified by invert. */
4718 /* Get the assignment statement of a WHERE statement, or the first
4719 statement in where-body-construct of a WHERE construct. */
4720 cnext = cblock->next;
4721 while (cnext)
4723 switch (cnext->op)
4725 /* WHERE assignment statement. */
4726 case EXEC_ASSIGN_CALL:
4728 arg = cnext->ext.actual;
4729 expr1 = expr2 = NULL;
4730 for (; arg; arg = arg->next)
4732 if (!arg->expr)
4733 continue;
4734 if (expr1 == NULL)
4735 expr1 = arg->expr;
4736 else
4737 expr2 = arg->expr;
4739 goto evaluate;
4741 case EXEC_ASSIGN:
4742 expr1 = cnext->expr1;
4743 expr2 = cnext->expr2;
4744 evaluate:
4745 if (nested_forall_info != NULL)
4747 need_temp = gfc_check_dependency (expr1, expr2, 0);
4748 if (need_temp && cnext->op != EXEC_ASSIGN_CALL)
4749 gfc_trans_assign_need_temp (expr1, expr2,
4750 cmask, invert,
4751 nested_forall_info, block);
4752 else
4754 /* Variables to control maskexpr. */
4755 count1 = gfc_create_var (gfc_array_index_type, "count1");
4756 count2 = gfc_create_var (gfc_array_index_type, "count2");
4757 gfc_add_modify (block, count1, gfc_index_zero_node);
4758 gfc_add_modify (block, count2, gfc_index_zero_node);
4760 tmp = gfc_trans_where_assign (expr1, expr2,
4761 cmask, invert,
4762 count1, count2,
4763 cnext);
4765 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4766 tmp, 1);
4767 gfc_add_expr_to_block (block, tmp);
4770 else
4772 /* Variables to control maskexpr. */
4773 count1 = gfc_create_var (gfc_array_index_type, "count1");
4774 count2 = gfc_create_var (gfc_array_index_type, "count2");
4775 gfc_add_modify (block, count1, gfc_index_zero_node);
4776 gfc_add_modify (block, count2, gfc_index_zero_node);
4778 tmp = gfc_trans_where_assign (expr1, expr2,
4779 cmask, invert,
4780 count1, count2,
4781 cnext);
4782 gfc_add_expr_to_block (block, tmp);
4785 break;
4787 /* WHERE or WHERE construct is part of a where-body-construct. */
4788 case EXEC_WHERE:
4789 gfc_trans_where_2 (cnext, cmask, invert,
4790 nested_forall_info, block);
4791 break;
4793 default:
4794 gcc_unreachable ();
4797 /* The next statement within the same where-body-construct. */
4798 cnext = cnext->next;
4800 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
4801 cblock = cblock->block;
4802 if (mask == NULL_TREE)
4804 /* If we're the initial WHERE, we can simply invert the sense
4805 of the current mask to obtain the "mask" for the remaining
4806 ELSEWHEREs. */
4807 invert = true;
4808 mask = cmask;
4810 else
4812 /* Otherwise, for nested WHERE's we need to use the pending mask. */
4813 invert = false;
4814 mask = pmask;
4818 /* If we allocated a pending mask array, deallocate it now. */
4819 if (ppmask)
4821 tmp = gfc_call_free (ppmask);
4822 gfc_add_expr_to_block (block, tmp);
4825 /* If we allocated a current mask array, deallocate it now. */
4826 if (pcmask)
4828 tmp = gfc_call_free (pcmask);
4829 gfc_add_expr_to_block (block, tmp);
4833 /* Translate a simple WHERE construct or statement without dependencies.
4834 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
4835 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
4836 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
4838 static tree
4839 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
4841 stmtblock_t block, body;
4842 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
4843 tree tmp, cexpr, tstmt, estmt;
4844 gfc_ss *css, *tdss, *tsss;
4845 gfc_se cse, tdse, tsse, edse, esse;
4846 gfc_loopinfo loop;
4847 gfc_ss *edss = 0;
4848 gfc_ss *esss = 0;
4850 /* Allow the scalarizer to workshare simple where loops. */
4851 if (ompws_flags & OMPWS_WORKSHARE_FLAG)
4852 ompws_flags |= OMPWS_SCALARIZER_WS;
4854 cond = cblock->expr1;
4855 tdst = cblock->next->expr1;
4856 tsrc = cblock->next->expr2;
4857 edst = eblock ? eblock->next->expr1 : NULL;
4858 esrc = eblock ? eblock->next->expr2 : NULL;
4860 gfc_start_block (&block);
4861 gfc_init_loopinfo (&loop);
4863 /* Handle the condition. */
4864 gfc_init_se (&cse, NULL);
4865 css = gfc_walk_expr (cond);
4866 gfc_add_ss_to_loop (&loop, css);
4868 /* Handle the then-clause. */
4869 gfc_init_se (&tdse, NULL);
4870 gfc_init_se (&tsse, NULL);
4871 tdss = gfc_walk_expr (tdst);
4872 tsss = gfc_walk_expr (tsrc);
4873 if (tsss == gfc_ss_terminator)
4875 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
4876 tsss->info->where = 1;
4878 gfc_add_ss_to_loop (&loop, tdss);
4879 gfc_add_ss_to_loop (&loop, tsss);
4881 if (eblock)
4883 /* Handle the else clause. */
4884 gfc_init_se (&edse, NULL);
4885 gfc_init_se (&esse, NULL);
4886 edss = gfc_walk_expr (edst);
4887 esss = gfc_walk_expr (esrc);
4888 if (esss == gfc_ss_terminator)
4890 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
4891 esss->info->where = 1;
4893 gfc_add_ss_to_loop (&loop, edss);
4894 gfc_add_ss_to_loop (&loop, esss);
4897 gfc_conv_ss_startstride (&loop);
4898 gfc_conv_loop_setup (&loop, &tdst->where);
4900 gfc_mark_ss_chain_used (css, 1);
4901 gfc_mark_ss_chain_used (tdss, 1);
4902 gfc_mark_ss_chain_used (tsss, 1);
4903 if (eblock)
4905 gfc_mark_ss_chain_used (edss, 1);
4906 gfc_mark_ss_chain_used (esss, 1);
4909 gfc_start_scalarized_body (&loop, &body);
4911 gfc_copy_loopinfo_to_se (&cse, &loop);
4912 gfc_copy_loopinfo_to_se (&tdse, &loop);
4913 gfc_copy_loopinfo_to_se (&tsse, &loop);
4914 cse.ss = css;
4915 tdse.ss = tdss;
4916 tsse.ss = tsss;
4917 if (eblock)
4919 gfc_copy_loopinfo_to_se (&edse, &loop);
4920 gfc_copy_loopinfo_to_se (&esse, &loop);
4921 edse.ss = edss;
4922 esse.ss = esss;
4925 gfc_conv_expr (&cse, cond);
4926 gfc_add_block_to_block (&body, &cse.pre);
4927 cexpr = cse.expr;
4929 gfc_conv_expr (&tsse, tsrc);
4930 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
4931 gfc_conv_tmp_array_ref (&tdse);
4932 else
4933 gfc_conv_expr (&tdse, tdst);
4935 if (eblock)
4937 gfc_conv_expr (&esse, esrc);
4938 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
4939 gfc_conv_tmp_array_ref (&edse);
4940 else
4941 gfc_conv_expr (&edse, edst);
4944 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
4945 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
4946 false, true)
4947 : build_empty_stmt (input_location);
4948 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
4949 gfc_add_expr_to_block (&body, tmp);
4950 gfc_add_block_to_block (&body, &cse.post);
4952 gfc_trans_scalarizing_loops (&loop, &body);
4953 gfc_add_block_to_block (&block, &loop.pre);
4954 gfc_add_block_to_block (&block, &loop.post);
4955 gfc_cleanup_loop (&loop);
4957 return gfc_finish_block (&block);
4960 /* As the WHERE or WHERE construct statement can be nested, we call
4961 gfc_trans_where_2 to do the translation, and pass the initial
4962 NULL values for both the control mask and the pending control mask. */
4964 tree
4965 gfc_trans_where (gfc_code * code)
4967 stmtblock_t block;
4968 gfc_code *cblock;
4969 gfc_code *eblock;
4971 cblock = code->block;
4972 if (cblock->next
4973 && cblock->next->op == EXEC_ASSIGN
4974 && !cblock->next->next)
4976 eblock = cblock->block;
4977 if (!eblock)
4979 /* A simple "WHERE (cond) x = y" statement or block is
4980 dependence free if cond is not dependent upon writing x,
4981 and the source y is unaffected by the destination x. */
4982 if (!gfc_check_dependency (cblock->next->expr1,
4983 cblock->expr1, 0)
4984 && !gfc_check_dependency (cblock->next->expr1,
4985 cblock->next->expr2, 0))
4986 return gfc_trans_where_3 (cblock, NULL);
4988 else if (!eblock->expr1
4989 && !eblock->block
4990 && eblock->next
4991 && eblock->next->op == EXEC_ASSIGN
4992 && !eblock->next->next)
4994 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
4995 block is dependence free if cond is not dependent on writes
4996 to x1 and x2, y1 is not dependent on writes to x2, and y2
4997 is not dependent on writes to x1, and both y's are not
4998 dependent upon their own x's. In addition to this, the
4999 final two dependency checks below exclude all but the same
5000 array reference if the where and elswhere destinations
5001 are the same. In short, this is VERY conservative and this
5002 is needed because the two loops, required by the standard
5003 are coalesced in gfc_trans_where_3. */
5004 if (!gfc_check_dependency (cblock->next->expr1,
5005 cblock->expr1, 0)
5006 && !gfc_check_dependency (eblock->next->expr1,
5007 cblock->expr1, 0)
5008 && !gfc_check_dependency (cblock->next->expr1,
5009 eblock->next->expr2, 1)
5010 && !gfc_check_dependency (eblock->next->expr1,
5011 cblock->next->expr2, 1)
5012 && !gfc_check_dependency (cblock->next->expr1,
5013 cblock->next->expr2, 1)
5014 && !gfc_check_dependency (eblock->next->expr1,
5015 eblock->next->expr2, 1)
5016 && !gfc_check_dependency (cblock->next->expr1,
5017 eblock->next->expr1, 0)
5018 && !gfc_check_dependency (eblock->next->expr1,
5019 cblock->next->expr1, 0))
5020 return gfc_trans_where_3 (cblock, eblock);
5024 gfc_start_block (&block);
5026 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5028 return gfc_finish_block (&block);
5032 /* CYCLE a DO loop. The label decl has already been created by
5033 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5034 node at the head of the loop. We must mark the label as used. */
5036 tree
5037 gfc_trans_cycle (gfc_code * code)
5039 tree cycle_label;
5041 cycle_label = code->ext.which_construct->cycle_label;
5042 gcc_assert (cycle_label);
5044 TREE_USED (cycle_label) = 1;
5045 return build1_v (GOTO_EXPR, cycle_label);
5049 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5050 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5051 loop. */
5053 tree
5054 gfc_trans_exit (gfc_code * code)
5056 tree exit_label;
5058 exit_label = code->ext.which_construct->exit_label;
5059 gcc_assert (exit_label);
5061 TREE_USED (exit_label) = 1;
5062 return build1_v (GOTO_EXPR, exit_label);
5066 /* Translate the ALLOCATE statement. */
5068 tree
5069 gfc_trans_allocate (gfc_code * code)
5071 gfc_alloc *al;
5072 gfc_expr *expr, *e3rhs = NULL;
5073 gfc_se se, se_sz;
5074 tree tmp;
5075 tree parm;
5076 tree stat;
5077 tree errmsg;
5078 tree errlen;
5079 tree label_errmsg;
5080 tree label_finish;
5081 tree memsz;
5082 tree al_vptr, al_len;
5083 tree def_str_len = NULL_TREE;
5084 /* If an expr3 is present, then store the tree for accessing its
5085 _vptr, and _len components in the variables, respectively. The
5086 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5087 the trees may be the NULL_TREE indicating that this is not
5088 available for expr3's type. */
5089 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5090 /* Classify what expr3 stores. */
5091 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5092 stmtblock_t block;
5093 stmtblock_t post;
5094 tree nelems;
5095 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
5096 gfc_symtree *newsym = NULL;
5098 if (!code->ext.alloc.list)
5099 return NULL_TREE;
5101 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5102 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5103 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5104 e3_is = E3_UNSET;
5106 gfc_init_block (&block);
5107 gfc_init_block (&post);
5109 /* STAT= (and maybe ERRMSG=) is present. */
5110 if (code->expr1)
5112 /* STAT=. */
5113 tree gfc_int4_type_node = gfc_get_int_type (4);
5114 stat = gfc_create_var (gfc_int4_type_node, "stat");
5116 /* ERRMSG= only makes sense with STAT=. */
5117 if (code->expr2)
5119 gfc_init_se (&se, NULL);
5120 se.want_pointer = 1;
5121 gfc_conv_expr_lhs (&se, code->expr2);
5122 errmsg = se.expr;
5123 errlen = se.string_length;
5125 else
5127 errmsg = null_pointer_node;
5128 errlen = build_int_cst (gfc_charlen_type_node, 0);
5131 /* GOTO destinations. */
5132 label_errmsg = gfc_build_label_decl (NULL_TREE);
5133 label_finish = gfc_build_label_decl (NULL_TREE);
5134 TREE_USED (label_finish) = 0;
5137 /* When an expr3 is present evaluate it only once. The standards prevent a
5138 dependency of expr3 on the objects in the allocate list. An expr3 can
5139 be pre-evaluated in all cases. One just has to make sure, to use the
5140 correct way, i.e., to get the descriptor or to get a reference
5141 expression. */
5142 if (code->expr3)
5144 bool vtab_needed = false, temp_var_needed = false;
5146 /* Figure whether we need the vtab from expr3. */
5147 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5148 al = al->next)
5149 vtab_needed = (al->expr->ts.type == BT_CLASS);
5151 gfc_init_se (&se, NULL);
5152 /* When expr3 is a variable, i.e., a very simple expression,
5153 then convert it once here. */
5154 if (code->expr3->expr_type == EXPR_VARIABLE
5155 || code->expr3->expr_type == EXPR_ARRAY
5156 || code->expr3->expr_type == EXPR_CONSTANT)
5158 if (!code->expr3->mold
5159 || code->expr3->ts.type == BT_CHARACTER
5160 || vtab_needed
5161 || code->ext.alloc.arr_spec_from_expr3)
5163 /* Convert expr3 to a tree. For all "simple" expression just
5164 get the descriptor or the reference, respectively, depending
5165 on the rank of the expr. */
5166 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5167 gfc_conv_expr_descriptor (&se, code->expr3);
5168 else
5169 gfc_conv_expr_reference (&se, code->expr3);
5170 /* Create a temp variable only for component refs to prevent
5171 having to go through the full deref-chain each time and to
5172 simplfy computation of array properties. */
5173 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5176 else
5178 /* In all other cases evaluate the expr3. */
5179 symbol_attribute attr;
5180 /* Get the descriptor for all arrays, that are not allocatable or
5181 pointer, because the latter are descriptors already.
5182 The exception are function calls returning a class object:
5183 The descriptor is stored in their results _data component, which
5184 is easier to access, when first a temporary variable for the
5185 result is created and the descriptor retrieved from there. */
5186 attr = gfc_expr_attr (code->expr3);
5187 if (code->expr3->rank != 0
5188 && ((!attr.allocatable && !attr.pointer)
5189 || (code->expr3->expr_type == EXPR_FUNCTION
5190 && code->expr3->ts.type != BT_CLASS)))
5191 gfc_conv_expr_descriptor (&se, code->expr3);
5192 else
5193 gfc_conv_expr_reference (&se, code->expr3);
5194 if (code->expr3->ts.type == BT_CLASS)
5195 gfc_conv_class_to_class (&se, code->expr3,
5196 code->expr3->ts,
5197 false, true,
5198 false, false);
5199 temp_var_needed = !VAR_P (se.expr);
5201 gfc_add_block_to_block (&block, &se.pre);
5202 gfc_add_block_to_block (&post, &se.post);
5203 /* Prevent aliasing, i.e., se.expr may be already a
5204 variable declaration. */
5205 if (se.expr != NULL_TREE && temp_var_needed)
5207 tree var, desc;
5208 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) ?
5209 se.expr
5210 : build_fold_indirect_ref_loc (input_location, se.expr);
5212 /* Get the array descriptor and prepare it to be assigned to the
5213 temporary variable var. For classes the array descriptor is
5214 in the _data component and the object goes into the
5215 GFC_DECL_SAVED_DESCRIPTOR. */
5216 if (code->expr3->ts.type == BT_CLASS
5217 && code->expr3->rank != 0)
5219 /* When an array_ref was in expr3, then the descriptor is the
5220 first operand. */
5221 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
5223 desc = TREE_OPERAND (tmp, 0);
5225 else
5227 desc = tmp;
5228 tmp = gfc_class_data_get (tmp);
5230 e3_is = E3_DESC;
5232 else
5233 desc = se.expr;
5234 /* We need a regular (non-UID) symbol here, therefore give a
5235 prefix. */
5236 var = gfc_create_var (TREE_TYPE (tmp), "source");
5237 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)))
5239 gfc_allocate_lang_decl (var);
5240 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5242 gfc_add_modify_loc (input_location, &block, var, tmp);
5244 /* Deallocate any allocatable components after all the allocations
5245 and assignments of expr3 have been completed. */
5246 if (code->expr3->ts.type == BT_DERIVED
5247 && code->expr3->rank == 0
5248 && code->expr3->ts.u.derived->attr.alloc_comp)
5250 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5251 var, 0);
5252 gfc_add_expr_to_block (&post, tmp);
5255 expr3 = var;
5256 if (se.string_length)
5257 /* Evaluate it assuming that it also is complicated like expr3. */
5258 expr3_len = gfc_evaluate_now (se.string_length, &block);
5260 else
5262 expr3 = se.expr;
5263 expr3_len = se.string_length;
5265 /* Store what the expr3 is to be used for. */
5266 if (e3_is == E3_UNSET)
5267 e3_is = expr3 != NULL_TREE ?
5268 (code->ext.alloc.arr_spec_from_expr3 ?
5269 E3_DESC
5270 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
5271 : E3_UNSET;
5273 /* Figure how to get the _vtab entry. This also obtains the tree
5274 expression for accessing the _len component, because only
5275 unlimited polymorphic objects, which are a subcategory of class
5276 types, have a _len component. */
5277 if (code->expr3->ts.type == BT_CLASS)
5279 gfc_expr *rhs;
5280 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
5281 build_fold_indirect_ref (expr3): expr3;
5282 /* Polymorphic SOURCE: VPTR must be determined at run time.
5283 expr3 may be a temporary array declaration, therefore check for
5284 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5285 if (tmp != NULL_TREE
5286 && TREE_CODE (tmp) != POINTER_PLUS_EXPR
5287 && (e3_is == E3_DESC
5288 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
5289 && (VAR_P (tmp) || !code->expr3->ref))
5290 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
5291 tmp = gfc_class_vptr_get (expr3);
5292 else
5294 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5295 gfc_add_vptr_component (rhs);
5296 gfc_init_se (&se, NULL);
5297 se.want_pointer = 1;
5298 gfc_conv_expr (&se, rhs);
5299 tmp = se.expr;
5300 gfc_free_expr (rhs);
5302 /* Set the element size. */
5303 expr3_esize = gfc_vptr_size_get (tmp);
5304 if (vtab_needed)
5305 expr3_vptr = tmp;
5306 /* Initialize the ref to the _len component. */
5307 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5309 /* Same like for retrieving the _vptr. */
5310 if (expr3 != NULL_TREE && !code->expr3->ref)
5311 expr3_len = gfc_class_len_get (expr3);
5312 else
5314 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5315 gfc_add_len_component (rhs);
5316 gfc_init_se (&se, NULL);
5317 gfc_conv_expr (&se, rhs);
5318 expr3_len = se.expr;
5319 gfc_free_expr (rhs);
5323 else
5325 /* When the object to allocate is polymorphic type, then it
5326 needs its vtab set correctly, so deduce the required _vtab
5327 and _len from the source expression. */
5328 if (vtab_needed)
5330 /* VPTR is fixed at compile time. */
5331 gfc_symbol *vtab;
5333 vtab = gfc_find_vtab (&code->expr3->ts);
5334 gcc_assert (vtab);
5335 expr3_vptr = gfc_get_symbol_decl (vtab);
5336 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5337 expr3_vptr);
5339 /* _len component needs to be set, when ts is a character
5340 array. */
5341 if (expr3_len == NULL_TREE
5342 && code->expr3->ts.type == BT_CHARACTER)
5344 if (code->expr3->ts.u.cl
5345 && code->expr3->ts.u.cl->length)
5347 gfc_init_se (&se, NULL);
5348 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5349 gfc_add_block_to_block (&block, &se.pre);
5350 expr3_len = gfc_evaluate_now (se.expr, &block);
5352 gcc_assert (expr3_len);
5354 /* For character arrays only the kind's size is needed, because
5355 the array mem_size is _len * (elem_size = kind_size).
5356 For all other get the element size in the normal way. */
5357 if (code->expr3->ts.type == BT_CHARACTER)
5358 expr3_esize = TYPE_SIZE_UNIT (
5359 gfc_get_char_type (code->expr3->ts.kind));
5360 else
5361 expr3_esize = TYPE_SIZE_UNIT (
5362 gfc_typenode_for_spec (&code->expr3->ts));
5364 /* The routine gfc_trans_assignment () already implements all
5365 techniques needed. Unfortunately we may have a temporary
5366 variable for the source= expression here. When that is the
5367 case convert this variable into a temporary gfc_expr of type
5368 EXPR_VARIABLE and used it as rhs for the assignment. The
5369 advantage is, that we get scalarizer support for free,
5370 don't have to take care about scalar to array treatment and
5371 will benefit of every enhancements gfc_trans_assignment ()
5372 gets.
5373 No need to check whether e3_is is E3_UNSET, because that is
5374 done by expr3 != NULL_TREE.
5375 Exclude variables since the following block does not handle
5376 array sections. In any case, there is no harm in sending
5377 variables to gfc_trans_assignment because there is no
5378 evaluation of variables. */
5379 if (code->expr3->expr_type != EXPR_VARIABLE
5380 && e3_is != E3_MOLD && expr3 != NULL_TREE
5381 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
5383 /* Build a temporary symtree and symbol. Do not add it to
5384 the current namespace to prevent accidently modifying
5385 a colliding symbol's as. */
5386 newsym = XCNEW (gfc_symtree);
5387 /* The name of the symtree should be unique, because
5388 gfc_create_var () took care about generating the
5389 identifier. */
5390 newsym->name = gfc_get_string (IDENTIFIER_POINTER (
5391 DECL_NAME (expr3)));
5392 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
5393 /* The backend_decl is known. It is expr3, which is inserted
5394 here. */
5395 newsym->n.sym->backend_decl = expr3;
5396 e3rhs = gfc_get_expr ();
5397 e3rhs->ts = code->expr3->ts;
5398 e3rhs->rank = code->expr3->rank;
5399 e3rhs->symtree = newsym;
5400 /* Mark the symbol referenced or gfc_trans_assignment will
5401 bug. */
5402 newsym->n.sym->attr.referenced = 1;
5403 e3rhs->expr_type = EXPR_VARIABLE;
5404 e3rhs->where = code->expr3->where;
5405 /* Set the symbols type, upto it was BT_UNKNOWN. */
5406 newsym->n.sym->ts = e3rhs->ts;
5407 /* Check whether the expr3 is array valued. */
5408 if (e3rhs->rank)
5410 gfc_array_spec *arr;
5411 arr = gfc_get_array_spec ();
5412 arr->rank = e3rhs->rank;
5413 arr->type = AS_DEFERRED;
5414 /* Set the dimension and pointer attribute for arrays
5415 to be on the safe side. */
5416 newsym->n.sym->attr.dimension = 1;
5417 newsym->n.sym->attr.pointer = 1;
5418 newsym->n.sym->as = arr;
5419 gfc_add_full_array_ref (e3rhs, arr);
5421 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
5422 newsym->n.sym->attr.pointer = 1;
5423 /* The string length is known to. Set it for char arrays. */
5424 if (e3rhs->ts.type == BT_CHARACTER)
5425 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
5426 gfc_commit_symbol (newsym->n.sym);
5428 else
5429 e3rhs = gfc_copy_expr (code->expr3);
5431 gcc_assert (expr3_esize);
5432 expr3_esize = fold_convert (sizetype, expr3_esize);
5433 if (e3_is == E3_MOLD)
5435 /* The expr3 is no longer valid after this point. */
5436 expr3 = NULL_TREE;
5437 e3_is = E3_UNSET;
5440 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5442 /* Compute the explicit typespec given only once for all objects
5443 to allocate. */
5444 if (code->ext.alloc.ts.type != BT_CHARACTER)
5445 expr3_esize = TYPE_SIZE_UNIT (
5446 gfc_typenode_for_spec (&code->ext.alloc.ts));
5447 else
5449 gfc_expr *sz;
5450 gcc_assert (code->ext.alloc.ts.u.cl->length != NULL);
5451 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5452 gfc_init_se (&se_sz, NULL);
5453 gfc_conv_expr (&se_sz, sz);
5454 gfc_free_expr (sz);
5455 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5456 tmp = TYPE_SIZE_UNIT (tmp);
5457 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5458 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5459 TREE_TYPE (se_sz.expr),
5460 tmp, se_sz.expr);
5461 def_str_len = gfc_evaluate_now (se_sz.expr, &block);
5465 /* Loop over all objects to allocate. */
5466 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5468 expr = gfc_copy_expr (al->expr);
5469 /* UNLIMITED_POLY () needs the _data component to be set, when
5470 expr is a unlimited polymorphic object. But the _data component
5471 has not been set yet, so check the derived type's attr for the
5472 unlimited polymorphic flag to be safe. */
5473 upoly_expr = UNLIMITED_POLY (expr)
5474 || (expr->ts.type == BT_DERIVED
5475 && expr->ts.u.derived->attr.unlimited_polymorphic);
5476 gfc_init_se (&se, NULL);
5478 /* For class types prepare the expressions to ref the _vptr
5479 and the _len component. The latter for unlimited polymorphic
5480 types only. */
5481 if (expr->ts.type == BT_CLASS)
5483 gfc_expr *expr_ref_vptr, *expr_ref_len;
5484 gfc_add_data_component (expr);
5485 /* Prep the vptr handle. */
5486 expr_ref_vptr = gfc_copy_expr (al->expr);
5487 gfc_add_vptr_component (expr_ref_vptr);
5488 se.want_pointer = 1;
5489 gfc_conv_expr (&se, expr_ref_vptr);
5490 al_vptr = se.expr;
5491 se.want_pointer = 0;
5492 gfc_free_expr (expr_ref_vptr);
5493 /* Allocated unlimited polymorphic objects always have a _len
5494 component. */
5495 if (upoly_expr)
5497 expr_ref_len = gfc_copy_expr (al->expr);
5498 gfc_add_len_component (expr_ref_len);
5499 gfc_conv_expr (&se, expr_ref_len);
5500 al_len = se.expr;
5501 gfc_free_expr (expr_ref_len);
5503 else
5504 /* In a loop ensure that all loop variable dependent variables
5505 are initialized at the same spot in all execution paths. */
5506 al_len = NULL_TREE;
5508 else
5509 al_vptr = al_len = NULL_TREE;
5511 se.want_pointer = 1;
5512 se.descriptor_only = 1;
5514 if (expr->ts.type == BT_CHARACTER
5515 && expr->ts.deferred
5516 && TREE_CODE (expr->ts.u.cl->backend_decl) == VAR_DECL
5517 && def_str_len != NULL_TREE)
5519 tmp = expr->ts.u.cl->backend_decl;
5520 gfc_add_modify (&block, tmp,
5521 fold_convert (TREE_TYPE (tmp), def_str_len));
5524 gfc_conv_expr (&se, expr);
5525 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5526 /* se.string_length now stores the .string_length variable of expr
5527 needed to allocate character(len=:) arrays. */
5528 al_len = se.string_length;
5530 al_len_needs_set = al_len != NULL_TREE;
5531 /* When allocating an array one can not use much of the
5532 pre-evaluated expr3 expressions, because for most of them the
5533 scalarizer is needed which is not available in the pre-evaluation
5534 step. Therefore gfc_array_allocate () is responsible (and able)
5535 to handle the complete array allocation. Only the element size
5536 needs to be provided, which is done most of the time by the
5537 pre-evaluation step. */
5538 nelems = NULL_TREE;
5539 if (expr3_len && code->expr3->ts.type == BT_CHARACTER)
5540 /* When al is an array, then the element size for each element
5541 in the array is needed, which is the product of the len and
5542 esize for char arrays. */
5543 tmp = fold_build2_loc (input_location, MULT_EXPR,
5544 TREE_TYPE (expr3_esize), expr3_esize,
5545 fold_convert (TREE_TYPE (expr3_esize),
5546 expr3_len));
5547 else
5548 tmp = expr3_esize;
5549 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
5550 label_finish, tmp, &nelems,
5551 e3rhs ? e3rhs : code->expr3,
5552 e3_is == E3_DESC ? expr3 : NULL_TREE,
5553 code->expr3 != NULL && e3_is == E3_DESC
5554 && code->expr3->expr_type == EXPR_ARRAY))
5556 /* A scalar or derived type. First compute the size to
5557 allocate.
5559 expr3_len is set when expr3 is an unlimited polymorphic
5560 object or a deferred length string. */
5561 if (expr3_len != NULL_TREE)
5563 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
5564 tmp = fold_build2_loc (input_location, MULT_EXPR,
5565 TREE_TYPE (expr3_esize),
5566 expr3_esize, tmp);
5567 if (code->expr3->ts.type != BT_CLASS)
5568 /* expr3 is a deferred length string, i.e., we are
5569 done. */
5570 memsz = tmp;
5571 else
5573 /* For unlimited polymorphic enties build
5574 (len > 0) ? element_size * len : element_size
5575 to compute the number of bytes to allocate.
5576 This allows the allocation of unlimited polymorphic
5577 objects from an expr3 that is also unlimited
5578 polymorphic and stores a _len dependent object,
5579 e.g., a string. */
5580 memsz = fold_build2_loc (input_location, GT_EXPR,
5581 boolean_type_node, expr3_len,
5582 integer_zero_node);
5583 memsz = fold_build3_loc (input_location, COND_EXPR,
5584 TREE_TYPE (expr3_esize),
5585 memsz, tmp, expr3_esize);
5588 else if (expr3_esize != NULL_TREE)
5589 /* Any other object in expr3 just needs element size in
5590 bytes. */
5591 memsz = expr3_esize;
5592 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5593 || (upoly_expr
5594 && code->ext.alloc.ts.type == BT_CHARACTER))
5596 /* Allocating deferred length char arrays need the length
5597 to allocate in the alloc_type_spec. But also unlimited
5598 polymorphic objects may be allocated as char arrays.
5599 Both are handled here. */
5600 gfc_init_se (&se_sz, NULL);
5601 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5602 gfc_add_block_to_block (&se.pre, &se_sz.pre);
5603 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
5604 gfc_add_block_to_block (&se.pre, &se_sz.post);
5605 expr3_len = se_sz.expr;
5606 tmp_expr3_len_flag = true;
5607 tmp = TYPE_SIZE_UNIT (
5608 gfc_get_char_type (code->ext.alloc.ts.kind));
5609 memsz = fold_build2_loc (input_location, MULT_EXPR,
5610 TREE_TYPE (tmp),
5611 fold_convert (TREE_TYPE (tmp),
5612 expr3_len),
5613 tmp);
5615 else if (expr->ts.type == BT_CHARACTER)
5617 /* Compute the number of bytes needed to allocate a fixed
5618 length char array. */
5619 gcc_assert (se.string_length != NULL_TREE);
5620 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
5621 memsz = fold_build2_loc (input_location, MULT_EXPR,
5622 TREE_TYPE (tmp), tmp,
5623 fold_convert (TREE_TYPE (tmp),
5624 se.string_length));
5626 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5627 /* Handle all types, where the alloc_type_spec is set. */
5628 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
5629 else
5630 /* Handle size computation of the type declared to alloc. */
5631 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
5633 /* Allocate - for non-pointers with re-alloc checking. */
5634 if (gfc_expr_attr (expr).allocatable)
5635 gfc_allocate_allocatable (&se.pre, se.expr, memsz, NULL_TREE,
5636 stat, errmsg, errlen, label_finish,
5637 expr);
5638 else
5639 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
5641 if (al->expr->ts.type == BT_DERIVED
5642 && expr->ts.u.derived->attr.alloc_comp)
5644 tmp = build_fold_indirect_ref_loc (input_location, se.expr);
5645 tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, tmp, 0);
5646 gfc_add_expr_to_block (&se.pre, tmp);
5649 else
5651 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
5652 && expr3_len != NULL_TREE)
5654 /* Arrays need to have a _len set before the array
5655 descriptor is filled. */
5656 gfc_add_modify (&block, al_len,
5657 fold_convert (TREE_TYPE (al_len), expr3_len));
5658 /* Prevent setting the length twice. */
5659 al_len_needs_set = false;
5663 gfc_add_block_to_block (&block, &se.pre);
5665 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
5666 if (code->expr1)
5668 tmp = build1_v (GOTO_EXPR, label_errmsg);
5669 parm = fold_build2_loc (input_location, NE_EXPR,
5670 boolean_type_node, stat,
5671 build_int_cst (TREE_TYPE (stat), 0));
5672 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5673 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
5674 tmp, build_empty_stmt (input_location));
5675 gfc_add_expr_to_block (&block, tmp);
5678 /* Set the vptr. */
5679 if (al_vptr != NULL_TREE)
5681 if (expr3_vptr != NULL_TREE)
5682 /* The vtab is already known, so just assign it. */
5683 gfc_add_modify (&block, al_vptr,
5684 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
5685 else
5687 /* VPTR is fixed at compile time. */
5688 gfc_symbol *vtab;
5689 gfc_typespec *ts;
5691 if (code->expr3)
5692 /* Although expr3 is pre-evaluated above, it may happen,
5693 that for arrays or in mold= cases the pre-evaluation
5694 was not successful. In these rare cases take the vtab
5695 from the typespec of expr3 here. */
5696 ts = &code->expr3->ts;
5697 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
5698 /* The alloc_type_spec gives the type to allocate or the
5699 al is unlimited polymorphic, which enforces the use of
5700 an alloc_type_spec that is not necessarily a BT_DERIVED. */
5701 ts = &code->ext.alloc.ts;
5702 else
5703 /* Prepare for setting the vtab as declared. */
5704 ts = &expr->ts;
5706 vtab = gfc_find_vtab (ts);
5707 gcc_assert (vtab);
5708 tmp = gfc_build_addr_expr (NULL_TREE,
5709 gfc_get_symbol_decl (vtab));
5710 gfc_add_modify (&block, al_vptr,
5711 fold_convert (TREE_TYPE (al_vptr), tmp));
5715 /* Add assignment for string length. */
5716 if (al_len != NULL_TREE && al_len_needs_set)
5718 if (expr3_len != NULL_TREE)
5720 gfc_add_modify (&block, al_len,
5721 fold_convert (TREE_TYPE (al_len),
5722 expr3_len));
5723 /* When tmp_expr3_len_flag is set, then expr3_len is
5724 abused to carry the length information from the
5725 alloc_type. Clear it to prevent setting incorrect len
5726 information in future loop iterations. */
5727 if (tmp_expr3_len_flag)
5728 /* No need to reset tmp_expr3_len_flag, because the
5729 presence of an expr3 can not change within in the
5730 loop. */
5731 expr3_len = NULL_TREE;
5733 else if (code->ext.alloc.ts.type == BT_CHARACTER
5734 && code->ext.alloc.ts.u.cl->length)
5736 /* Cover the cases where a string length is explicitly
5737 specified by a type spec for deferred length character
5738 arrays or unlimited polymorphic objects without a
5739 source= or mold= expression. */
5740 gfc_init_se (&se_sz, NULL);
5741 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5742 gfc_add_modify (&block, al_len,
5743 fold_convert (TREE_TYPE (al_len),
5744 se_sz.expr));
5746 else
5747 /* No length information needed, because type to allocate
5748 has no length. Set _len to 0. */
5749 gfc_add_modify (&block, al_len,
5750 fold_convert (TREE_TYPE (al_len),
5751 integer_zero_node));
5753 if (code->expr3 && !code->expr3->mold)
5755 /* Initialization via SOURCE block (or static default initializer).
5756 Classes need some special handling, so catch them first. */
5757 if (expr3 != NULL_TREE
5758 && TREE_CODE (expr3) != POINTER_PLUS_EXPR
5759 && code->expr3->ts.type == BT_CLASS
5760 && (expr->ts.type == BT_CLASS
5761 || expr->ts.type == BT_DERIVED))
5763 /* copy_class_to_class can be used for class arrays, too.
5764 It just needs to be ensured, that the decl_saved_descriptor
5765 has a way to get to the vptr. */
5766 tree to;
5767 to = VAR_P (se.expr) ? se.expr : TREE_OPERAND (se.expr, 0);
5768 tmp = gfc_copy_class_to_class (expr3, to,
5769 nelems, upoly_expr);
5771 else if (al->expr->ts.type == BT_CLASS)
5773 gfc_actual_arglist *actual, *last_arg;
5774 gfc_expr *ppc;
5775 gfc_code *ppc_code;
5776 gfc_ref *ref, *dataref;
5777 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
5779 /* Do a polymorphic deep copy. */
5780 actual = gfc_get_actual_arglist ();
5781 actual->expr = gfc_copy_expr (rhs);
5782 if (rhs->ts.type == BT_CLASS)
5783 gfc_add_data_component (actual->expr);
5784 last_arg = actual->next = gfc_get_actual_arglist ();
5785 last_arg->expr = gfc_copy_expr (al->expr);
5786 last_arg->expr->ts.type = BT_CLASS;
5787 gfc_add_data_component (last_arg->expr);
5789 dataref = NULL;
5790 /* Make sure we go up through the reference chain to
5791 the _data reference, where the arrayspec is found. */
5792 for (ref = last_arg->expr->ref; ref; ref = ref->next)
5793 if (ref->type == REF_COMPONENT
5794 && strcmp (ref->u.c.component->name, "_data") == 0)
5795 dataref = ref;
5797 if (dataref && dataref->u.c.component->as)
5799 gfc_array_spec *as = dataref->u.c.component->as;
5800 gfc_free_ref_list (dataref->next);
5801 dataref->next = NULL;
5802 gfc_add_full_array_ref (last_arg->expr, as);
5803 gfc_resolve_expr (last_arg->expr);
5804 gcc_assert (last_arg->expr->ts.type == BT_CLASS
5805 || last_arg->expr->ts.type == BT_DERIVED);
5806 last_arg->expr->ts.type = BT_CLASS;
5808 if (rhs->ts.type == BT_CLASS)
5810 if (rhs->ref)
5811 ppc = gfc_find_and_cut_at_last_class_ref (rhs);
5812 else
5813 ppc = gfc_copy_expr (rhs);
5814 gfc_add_vptr_component (ppc);
5816 else
5817 ppc = gfc_lval_expr_from_sym (gfc_find_vtab (&rhs->ts));
5818 gfc_add_component_ref (ppc, "_copy");
5820 ppc_code = gfc_get_code (EXEC_CALL);
5821 ppc_code->resolved_sym = ppc->symtree->n.sym;
5822 ppc_code->loc = al->expr->where;
5823 /* Although '_copy' is set to be elemental in class.c, it is
5824 not staying that way. Find out why, sometime.... */
5825 ppc_code->resolved_sym->attr.elemental = 1;
5826 ppc_code->ext.actual = actual;
5827 ppc_code->expr1 = ppc;
5828 /* Since '_copy' is elemental, the scalarizer will take care
5829 of arrays in gfc_trans_call. */
5830 tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
5831 /* We need to add the
5832 if (al_len > 0)
5833 al_vptr->copy (expr3_data, al_data, expr3_len, al_len);
5834 else
5835 al_vptr->copy (expr3_data, al_data);
5836 block, because al is unlimited polymorphic or a deferred
5837 length char array, whose copy routine needs the array lengths
5838 as third and fourth arguments. */
5839 if (al_len && UNLIMITED_POLY (code->expr3))
5841 tree stdcopy, extcopy;
5842 /* Add al%_len. */
5843 last_arg->next = gfc_get_actual_arglist ();
5844 last_arg = last_arg->next;
5845 last_arg->expr = gfc_find_and_cut_at_last_class_ref (
5846 al->expr);
5847 gfc_add_len_component (last_arg->expr);
5848 /* Add expr3's length. */
5849 last_arg->next = gfc_get_actual_arglist ();
5850 last_arg = last_arg->next;
5851 if (code->expr3->ts.type == BT_CLASS)
5853 last_arg->expr =
5854 gfc_find_and_cut_at_last_class_ref (code->expr3);
5855 gfc_add_len_component (last_arg->expr);
5857 else if (code->expr3->ts.type == BT_CHARACTER)
5858 last_arg->expr =
5859 gfc_copy_expr (code->expr3->ts.u.cl->length);
5860 else
5861 gcc_unreachable ();
5863 stdcopy = tmp;
5864 extcopy = gfc_trans_call (ppc_code, true, NULL, NULL, false);
5866 tmp = fold_build2_loc (input_location, GT_EXPR,
5867 boolean_type_node, expr3_len,
5868 integer_zero_node);
5869 tmp = fold_build3_loc (input_location, COND_EXPR,
5870 void_type_node, tmp, extcopy, stdcopy);
5872 gfc_free_statements (ppc_code);
5873 if (rhs != e3rhs)
5874 gfc_free_expr (rhs);
5876 else
5878 /* Switch off automatic reallocation since we have just
5879 done the ALLOCATE. */
5880 int realloc_lhs = flag_realloc_lhs;
5881 flag_realloc_lhs = 0;
5882 tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
5883 e3rhs, false, false);
5884 flag_realloc_lhs = realloc_lhs;
5886 gfc_add_expr_to_block (&block, tmp);
5888 else if (code->expr3 && code->expr3->mold
5889 && code->expr3->ts.type == BT_CLASS)
5891 /* Since the _vptr has already been assigned to the allocate
5892 object, we can use gfc_copy_class_to_class in its
5893 initialization mode. */
5894 tmp = TREE_OPERAND (se.expr, 0);
5895 tmp = gfc_copy_class_to_class (NULL_TREE, tmp, nelems,
5896 upoly_expr);
5897 gfc_add_expr_to_block (&block, tmp);
5900 gfc_free_expr (expr);
5901 } // for-loop
5903 if (e3rhs)
5905 if (newsym)
5907 gfc_free_symbol (newsym->n.sym);
5908 XDELETE (newsym);
5910 gfc_free_expr (e3rhs);
5912 /* STAT. */
5913 if (code->expr1)
5915 tmp = build1_v (LABEL_EXPR, label_errmsg);
5916 gfc_add_expr_to_block (&block, tmp);
5919 /* ERRMSG - only useful if STAT is present. */
5920 if (code->expr1 && code->expr2)
5922 const char *msg = "Attempt to allocate an allocated object";
5923 tree slen, dlen, errmsg_str;
5924 stmtblock_t errmsg_block;
5926 gfc_init_block (&errmsg_block);
5928 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
5929 gfc_add_modify (&errmsg_block, errmsg_str,
5930 gfc_build_addr_expr (pchar_type_node,
5931 gfc_build_localized_cstring_const (msg)));
5933 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
5934 dlen = gfc_get_expr_charlen (code->expr2);
5935 slen = fold_build2_loc (input_location, MIN_EXPR,
5936 TREE_TYPE (slen), dlen, slen);
5938 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
5939 code->expr2->ts.kind,
5940 slen, errmsg_str,
5941 gfc_default_character_kind);
5942 dlen = gfc_finish_block (&errmsg_block);
5944 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5945 stat, build_int_cst (TREE_TYPE (stat), 0));
5947 tmp = build3_v (COND_EXPR, tmp,
5948 dlen, build_empty_stmt (input_location));
5950 gfc_add_expr_to_block (&block, tmp);
5953 /* STAT block. */
5954 if (code->expr1)
5956 if (TREE_USED (label_finish))
5958 tmp = build1_v (LABEL_EXPR, label_finish);
5959 gfc_add_expr_to_block (&block, tmp);
5962 gfc_init_se (&se, NULL);
5963 gfc_conv_expr_lhs (&se, code->expr1);
5964 tmp = convert (TREE_TYPE (se.expr), stat);
5965 gfc_add_modify (&block, se.expr, tmp);
5968 gfc_add_block_to_block (&block, &se.post);
5969 gfc_add_block_to_block (&block, &post);
5971 return gfc_finish_block (&block);
5975 /* Translate a DEALLOCATE statement. */
5977 tree
5978 gfc_trans_deallocate (gfc_code *code)
5980 gfc_se se;
5981 gfc_alloc *al;
5982 tree apstat, pstat, stat, errmsg, errlen, tmp;
5983 tree label_finish, label_errmsg;
5984 stmtblock_t block;
5986 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
5987 label_finish = label_errmsg = NULL_TREE;
5989 gfc_start_block (&block);
5991 /* Count the number of failed deallocations. If deallocate() was
5992 called with STAT= , then set STAT to the count. If deallocate
5993 was called with ERRMSG, then set ERRMG to a string. */
5994 if (code->expr1)
5996 tree gfc_int4_type_node = gfc_get_int_type (4);
5998 stat = gfc_create_var (gfc_int4_type_node, "stat");
5999 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6001 /* GOTO destinations. */
6002 label_errmsg = gfc_build_label_decl (NULL_TREE);
6003 label_finish = gfc_build_label_decl (NULL_TREE);
6004 TREE_USED (label_finish) = 0;
6007 /* Set ERRMSG - only needed if STAT is available. */
6008 if (code->expr1 && code->expr2)
6010 gfc_init_se (&se, NULL);
6011 se.want_pointer = 1;
6012 gfc_conv_expr_lhs (&se, code->expr2);
6013 errmsg = se.expr;
6014 errlen = se.string_length;
6017 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6019 gfc_expr *expr = gfc_copy_expr (al->expr);
6020 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6022 if (expr->ts.type == BT_CLASS)
6023 gfc_add_data_component (expr);
6025 gfc_init_se (&se, NULL);
6026 gfc_start_block (&se.pre);
6028 se.want_pointer = 1;
6029 se.descriptor_only = 1;
6030 gfc_conv_expr (&se, expr);
6032 if (expr->rank || gfc_is_coarray (expr))
6034 gfc_ref *ref;
6036 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp
6037 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6039 gfc_ref *last = NULL;
6041 for (ref = expr->ref; ref; ref = ref->next)
6042 if (ref->type == REF_COMPONENT)
6043 last = ref;
6045 /* Do not deallocate the components of a derived type
6046 ultimate pointer component. */
6047 if (!(last && last->u.c.component->attr.pointer)
6048 && !(!last && expr->symtree->n.sym->attr.pointer))
6050 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr,
6051 expr->rank);
6052 gfc_add_expr_to_block (&se.pre, tmp);
6056 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6058 tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen,
6059 label_finish, expr);
6060 gfc_add_expr_to_block (&se.pre, tmp);
6062 else if (TREE_CODE (se.expr) == COMPONENT_REF
6063 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6064 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6065 == RECORD_TYPE)
6067 /* class.c(finalize_component) generates these, when a
6068 finalizable entity has a non-allocatable derived type array
6069 component, which has allocatable components. Obtain the
6070 derived type of the array and deallocate the allocatable
6071 components. */
6072 for (ref = expr->ref; ref; ref = ref->next)
6074 if (ref->u.c.component->attr.dimension
6075 && ref->u.c.component->ts.type == BT_DERIVED)
6076 break;
6079 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6080 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6081 NULL))
6083 tmp = gfc_deallocate_alloc_comp
6084 (ref->u.c.component->ts.u.derived,
6085 se.expr, expr->rank);
6086 gfc_add_expr_to_block (&se.pre, tmp);
6090 if (al->expr->ts.type == BT_CLASS)
6092 gfc_reset_vptr (&se.pre, al->expr);
6093 if (UNLIMITED_POLY (al->expr)
6094 || (al->expr->ts.type == BT_DERIVED
6095 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6096 /* Clear _len, too. */
6097 gfc_reset_len (&se.pre, al->expr);
6100 else
6102 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, false,
6103 al->expr, al->expr->ts);
6104 gfc_add_expr_to_block (&se.pre, tmp);
6106 /* Set to zero after deallocation. */
6107 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6108 se.expr,
6109 build_int_cst (TREE_TYPE (se.expr), 0));
6110 gfc_add_expr_to_block (&se.pre, tmp);
6112 if (al->expr->ts.type == BT_CLASS)
6114 gfc_reset_vptr (&se.pre, al->expr);
6115 if (UNLIMITED_POLY (al->expr)
6116 || (al->expr->ts.type == BT_DERIVED
6117 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6118 /* Clear _len, too. */
6119 gfc_reset_len (&se.pre, al->expr);
6123 if (code->expr1)
6125 tree cond;
6127 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6128 build_int_cst (TREE_TYPE (stat), 0));
6129 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6130 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6131 build1_v (GOTO_EXPR, label_errmsg),
6132 build_empty_stmt (input_location));
6133 gfc_add_expr_to_block (&se.pre, tmp);
6136 tmp = gfc_finish_block (&se.pre);
6137 gfc_add_expr_to_block (&block, tmp);
6138 gfc_free_expr (expr);
6141 if (code->expr1)
6143 tmp = build1_v (LABEL_EXPR, label_errmsg);
6144 gfc_add_expr_to_block (&block, tmp);
6147 /* Set ERRMSG - only needed if STAT is available. */
6148 if (code->expr1 && code->expr2)
6150 const char *msg = "Attempt to deallocate an unallocated object";
6151 stmtblock_t errmsg_block;
6152 tree errmsg_str, slen, dlen, cond;
6154 gfc_init_block (&errmsg_block);
6156 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6157 gfc_add_modify (&errmsg_block, errmsg_str,
6158 gfc_build_addr_expr (pchar_type_node,
6159 gfc_build_localized_cstring_const (msg)));
6160 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6161 dlen = gfc_get_expr_charlen (code->expr2);
6163 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6164 slen, errmsg_str, gfc_default_character_kind);
6165 tmp = gfc_finish_block (&errmsg_block);
6167 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6168 build_int_cst (TREE_TYPE (stat), 0));
6169 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6170 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6171 build_empty_stmt (input_location));
6173 gfc_add_expr_to_block (&block, tmp);
6176 if (code->expr1 && TREE_USED (label_finish))
6178 tmp = build1_v (LABEL_EXPR, label_finish);
6179 gfc_add_expr_to_block (&block, tmp);
6182 /* Set STAT. */
6183 if (code->expr1)
6185 gfc_init_se (&se, NULL);
6186 gfc_conv_expr_lhs (&se, code->expr1);
6187 tmp = convert (TREE_TYPE (se.expr), stat);
6188 gfc_add_modify (&block, se.expr, tmp);
6191 return gfc_finish_block (&block);
6194 #include "gt-fortran-trans-stmt.h"