* config/spu/spu.md (floatunsdidf2): Remove unused local variable.
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob490b18dae31eb4e567abd0eadf48d37eb8ee35af
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2016 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 : (flag_coarray == GFC_FCOARRAY_LIB
639 ? gfor_fndecl_caf_stop_str
640 : gfor_fndecl_stop_string),
641 2, build_int_cst (pchar_type_node, 0), tmp);
643 else if (code->expr1->ts.type == BT_INTEGER)
645 gfc_conv_expr (&se, code->expr1);
646 tmp = build_call_expr_loc (input_location,
647 error_stop
648 ? (flag_coarray == GFC_FCOARRAY_LIB
649 ? gfor_fndecl_caf_error_stop
650 : gfor_fndecl_error_stop_numeric)
651 : (flag_coarray == GFC_FCOARRAY_LIB
652 ? gfor_fndecl_caf_stop_numeric
653 : gfor_fndecl_stop_numeric_f08), 1,
654 fold_convert (gfc_int4_type_node, se.expr));
656 else
658 gfc_conv_expr_reference (&se, code->expr1);
659 tmp = build_call_expr_loc (input_location,
660 error_stop
661 ? (flag_coarray == GFC_FCOARRAY_LIB
662 ? gfor_fndecl_caf_error_stop_str
663 : gfor_fndecl_error_stop_string)
664 : (flag_coarray == GFC_FCOARRAY_LIB
665 ? gfor_fndecl_caf_stop_str
666 : gfor_fndecl_stop_string),
667 2, se.expr, se.string_length);
670 gfc_add_expr_to_block (&se.pre, tmp);
672 gfc_add_block_to_block (&se.pre, &se.post);
674 return gfc_finish_block (&se.pre);
678 tree
679 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
681 gfc_se se, argse;
682 tree stat = NULL_TREE, stat2 = NULL_TREE;
683 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
685 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
686 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
687 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
688 return NULL_TREE;
690 if (code->expr2)
692 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
693 gfc_init_se (&argse, NULL);
694 gfc_conv_expr_val (&argse, code->expr2);
695 stat = argse.expr;
697 else if (flag_coarray == GFC_FCOARRAY_LIB)
698 stat = null_pointer_node;
700 if (code->expr4)
702 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
703 gfc_init_se (&argse, NULL);
704 gfc_conv_expr_val (&argse, code->expr4);
705 lock_acquired = argse.expr;
707 else if (flag_coarray == GFC_FCOARRAY_LIB)
708 lock_acquired = null_pointer_node;
710 gfc_start_block (&se.pre);
711 if (flag_coarray == GFC_FCOARRAY_LIB)
713 tree tmp, token, image_index, errmsg, errmsg_len;
714 tree index = size_zero_node;
715 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
717 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
718 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
719 != INTMOD_ISO_FORTRAN_ENV
720 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
721 != ISOFORTRAN_LOCK_TYPE)
723 gfc_error ("Sorry, the lock component of derived type at %L is not "
724 "yet supported", &code->expr1->where);
725 return NULL_TREE;
728 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
729 code->expr1);
731 if (gfc_is_coindexed (code->expr1))
732 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
733 else
734 image_index = integer_zero_node;
736 /* For arrays, obtain the array index. */
737 if (gfc_expr_attr (code->expr1).dimension)
739 tree desc, tmp, extent, lbound, ubound;
740 gfc_array_ref *ar, ar2;
741 int i;
743 /* TODO: Extend this, once DT components are supported. */
744 ar = &code->expr1->ref->u.ar;
745 ar2 = *ar;
746 memset (ar, '\0', sizeof (*ar));
747 ar->as = ar2.as;
748 ar->type = AR_FULL;
750 gfc_init_se (&argse, NULL);
751 argse.descriptor_only = 1;
752 gfc_conv_expr_descriptor (&argse, code->expr1);
753 gfc_add_block_to_block (&se.pre, &argse.pre);
754 desc = argse.expr;
755 *ar = ar2;
757 extent = integer_one_node;
758 for (i = 0; i < ar->dimen; i++)
760 gfc_init_se (&argse, NULL);
761 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
762 gfc_add_block_to_block (&argse.pre, &argse.pre);
763 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
764 tmp = fold_build2_loc (input_location, MINUS_EXPR,
765 integer_type_node, argse.expr,
766 fold_convert(integer_type_node, lbound));
767 tmp = fold_build2_loc (input_location, MULT_EXPR,
768 integer_type_node, extent, tmp);
769 index = fold_build2_loc (input_location, PLUS_EXPR,
770 integer_type_node, index, tmp);
771 if (i < ar->dimen - 1)
773 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
774 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
775 tmp = fold_convert (integer_type_node, tmp);
776 extent = fold_build2_loc (input_location, MULT_EXPR,
777 integer_type_node, extent, tmp);
782 /* errmsg. */
783 if (code->expr3)
785 gfc_init_se (&argse, NULL);
786 argse.want_pointer = 1;
787 gfc_conv_expr (&argse, code->expr3);
788 gfc_add_block_to_block (&se.pre, &argse.pre);
789 errmsg = argse.expr;
790 errmsg_len = fold_convert (integer_type_node, argse.string_length);
792 else
794 errmsg = null_pointer_node;
795 errmsg_len = integer_zero_node;
798 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
800 stat2 = stat;
801 stat = gfc_create_var (integer_type_node, "stat");
804 if (lock_acquired != null_pointer_node
805 && TREE_TYPE (lock_acquired) != integer_type_node)
807 lock_acquired2 = lock_acquired;
808 lock_acquired = gfc_create_var (integer_type_node, "acquired");
811 if (op == EXEC_LOCK)
812 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
813 token, index, image_index,
814 lock_acquired != null_pointer_node
815 ? gfc_build_addr_expr (NULL, lock_acquired)
816 : lock_acquired,
817 stat != null_pointer_node
818 ? gfc_build_addr_expr (NULL, stat) : stat,
819 errmsg, errmsg_len);
820 else
821 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
822 token, index, image_index,
823 stat != null_pointer_node
824 ? gfc_build_addr_expr (NULL, stat) : stat,
825 errmsg, errmsg_len);
826 gfc_add_expr_to_block (&se.pre, tmp);
828 /* It guarantees memory consistency within the same segment */
829 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
830 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
831 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
832 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
833 ASM_VOLATILE_P (tmp) = 1;
835 gfc_add_expr_to_block (&se.pre, tmp);
837 if (stat2 != NULL_TREE)
838 gfc_add_modify (&se.pre, stat2,
839 fold_convert (TREE_TYPE (stat2), stat));
841 if (lock_acquired2 != NULL_TREE)
842 gfc_add_modify (&se.pre, lock_acquired2,
843 fold_convert (TREE_TYPE (lock_acquired2),
844 lock_acquired));
846 return gfc_finish_block (&se.pre);
849 if (stat != NULL_TREE)
850 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
852 if (lock_acquired != NULL_TREE)
853 gfc_add_modify (&se.pre, lock_acquired,
854 fold_convert (TREE_TYPE (lock_acquired),
855 boolean_true_node));
857 return gfc_finish_block (&se.pre);
860 tree
861 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
863 gfc_se se, argse;
864 tree stat = NULL_TREE, stat2 = NULL_TREE;
865 tree until_count = NULL_TREE;
867 if (code->expr2)
869 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
870 gfc_init_se (&argse, NULL);
871 gfc_conv_expr_val (&argse, code->expr2);
872 stat = argse.expr;
874 else if (flag_coarray == GFC_FCOARRAY_LIB)
875 stat = null_pointer_node;
877 if (code->expr4)
879 gfc_init_se (&argse, NULL);
880 gfc_conv_expr_val (&argse, code->expr4);
881 until_count = fold_convert (integer_type_node, argse.expr);
883 else
884 until_count = integer_one_node;
886 if (flag_coarray != GFC_FCOARRAY_LIB)
888 gfc_start_block (&se.pre);
889 gfc_init_se (&argse, NULL);
890 gfc_conv_expr_val (&argse, code->expr1);
892 if (op == EXEC_EVENT_POST)
893 gfc_add_modify (&se.pre, argse.expr,
894 fold_build2_loc (input_location, PLUS_EXPR,
895 TREE_TYPE (argse.expr), argse.expr,
896 build_int_cst (TREE_TYPE (argse.expr), 1)));
897 else
898 gfc_add_modify (&se.pre, argse.expr,
899 fold_build2_loc (input_location, MINUS_EXPR,
900 TREE_TYPE (argse.expr), argse.expr,
901 fold_convert (TREE_TYPE (argse.expr),
902 until_count)));
903 if (stat != NULL_TREE)
904 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
906 return gfc_finish_block (&se.pre);
909 gfc_start_block (&se.pre);
910 tree tmp, token, image_index, errmsg, errmsg_len;
911 tree index = size_zero_node;
912 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
914 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
915 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
916 != INTMOD_ISO_FORTRAN_ENV
917 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
918 != ISOFORTRAN_EVENT_TYPE)
920 gfc_error ("Sorry, the event component of derived type at %L is not "
921 "yet supported", &code->expr1->where);
922 return NULL_TREE;
925 gfc_init_se (&argse, NULL);
926 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
927 code->expr1);
928 gfc_add_block_to_block (&se.pre, &argse.pre);
930 if (gfc_is_coindexed (code->expr1))
931 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
932 else
933 image_index = integer_zero_node;
935 /* For arrays, obtain the array index. */
936 if (gfc_expr_attr (code->expr1).dimension)
938 tree desc, tmp, extent, lbound, ubound;
939 gfc_array_ref *ar, ar2;
940 int i;
942 /* TODO: Extend this, once DT components are supported. */
943 ar = &code->expr1->ref->u.ar;
944 ar2 = *ar;
945 memset (ar, '\0', sizeof (*ar));
946 ar->as = ar2.as;
947 ar->type = AR_FULL;
949 gfc_init_se (&argse, NULL);
950 argse.descriptor_only = 1;
951 gfc_conv_expr_descriptor (&argse, code->expr1);
952 gfc_add_block_to_block (&se.pre, &argse.pre);
953 desc = argse.expr;
954 *ar = ar2;
956 extent = integer_one_node;
957 for (i = 0; i < ar->dimen; i++)
959 gfc_init_se (&argse, NULL);
960 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
961 gfc_add_block_to_block (&argse.pre, &argse.pre);
962 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
963 tmp = fold_build2_loc (input_location, MINUS_EXPR,
964 integer_type_node, argse.expr,
965 fold_convert(integer_type_node, lbound));
966 tmp = fold_build2_loc (input_location, MULT_EXPR,
967 integer_type_node, extent, tmp);
968 index = fold_build2_loc (input_location, PLUS_EXPR,
969 integer_type_node, index, tmp);
970 if (i < ar->dimen - 1)
972 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
973 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
974 tmp = fold_convert (integer_type_node, tmp);
975 extent = fold_build2_loc (input_location, MULT_EXPR,
976 integer_type_node, extent, tmp);
981 /* errmsg. */
982 if (code->expr3)
984 gfc_init_se (&argse, NULL);
985 argse.want_pointer = 1;
986 gfc_conv_expr (&argse, code->expr3);
987 gfc_add_block_to_block (&se.pre, &argse.pre);
988 errmsg = argse.expr;
989 errmsg_len = fold_convert (integer_type_node, argse.string_length);
991 else
993 errmsg = null_pointer_node;
994 errmsg_len = integer_zero_node;
997 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
999 stat2 = stat;
1000 stat = gfc_create_var (integer_type_node, "stat");
1003 if (op == EXEC_EVENT_POST)
1004 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1005 token, index, image_index,
1006 stat != null_pointer_node
1007 ? gfc_build_addr_expr (NULL, stat) : stat,
1008 errmsg, errmsg_len);
1009 else
1010 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1011 token, index, until_count,
1012 stat != null_pointer_node
1013 ? gfc_build_addr_expr (NULL, stat) : stat,
1014 errmsg, errmsg_len);
1015 gfc_add_expr_to_block (&se.pre, tmp);
1017 /* It guarantees memory consistency within the same segment */
1018 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1019 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1020 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1021 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1022 ASM_VOLATILE_P (tmp) = 1;
1023 gfc_add_expr_to_block (&se.pre, tmp);
1025 if (stat2 != NULL_TREE)
1026 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1028 return gfc_finish_block (&se.pre);
1031 tree
1032 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1034 gfc_se se, argse;
1035 tree tmp;
1036 tree images = NULL_TREE, stat = NULL_TREE,
1037 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1039 /* Short cut: For single images without bound checking or without STAT=,
1040 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1041 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1042 && flag_coarray != GFC_FCOARRAY_LIB)
1043 return NULL_TREE;
1045 gfc_init_se (&se, NULL);
1046 gfc_start_block (&se.pre);
1048 if (code->expr1 && code->expr1->rank == 0)
1050 gfc_init_se (&argse, NULL);
1051 gfc_conv_expr_val (&argse, code->expr1);
1052 images = argse.expr;
1055 if (code->expr2)
1057 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1058 gfc_init_se (&argse, NULL);
1059 gfc_conv_expr_val (&argse, code->expr2);
1060 stat = argse.expr;
1062 else
1063 stat = null_pointer_node;
1065 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1067 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1068 gfc_init_se (&argse, NULL);
1069 argse.want_pointer = 1;
1070 gfc_conv_expr (&argse, code->expr3);
1071 gfc_conv_string_parameter (&argse);
1072 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1073 errmsglen = argse.string_length;
1075 else if (flag_coarray == GFC_FCOARRAY_LIB)
1077 errmsg = null_pointer_node;
1078 errmsglen = build_int_cst (integer_type_node, 0);
1081 /* Check SYNC IMAGES(imageset) for valid image index.
1082 FIXME: Add a check for image-set arrays. */
1083 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1084 && code->expr1->rank == 0)
1086 tree cond;
1087 if (flag_coarray != GFC_FCOARRAY_LIB)
1088 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1089 images, build_int_cst (TREE_TYPE (images), 1));
1090 else
1092 tree cond2;
1093 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1094 2, integer_zero_node,
1095 build_int_cst (integer_type_node, -1));
1096 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1097 images, tmp);
1098 cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1099 images,
1100 build_int_cst (TREE_TYPE (images), 1));
1101 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1102 boolean_type_node, cond, cond2);
1104 gfc_trans_runtime_check (true, false, cond, &se.pre,
1105 &code->expr1->where, "Invalid image number "
1106 "%d in SYNC IMAGES",
1107 fold_convert (integer_type_node, images));
1110 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1111 image control statements SYNC IMAGES and SYNC ALL. */
1112 if (flag_coarray == GFC_FCOARRAY_LIB)
1114 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1115 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1116 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1117 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1118 ASM_VOLATILE_P (tmp) = 1;
1119 gfc_add_expr_to_block (&se.pre, tmp);
1122 if (flag_coarray != GFC_FCOARRAY_LIB)
1124 /* Set STAT to zero. */
1125 if (code->expr2)
1126 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1128 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1130 /* SYNC ALL => stat == null_pointer_node
1131 SYNC ALL(stat=s) => stat has an integer type
1133 If "stat" has the wrong integer type, use a temp variable of
1134 the right type and later cast the result back into "stat". */
1135 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1137 if (TREE_TYPE (stat) == integer_type_node)
1138 stat = gfc_build_addr_expr (NULL, stat);
1140 if(type == EXEC_SYNC_MEMORY)
1141 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1142 3, stat, errmsg, errmsglen);
1143 else
1144 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1145 3, stat, errmsg, errmsglen);
1147 gfc_add_expr_to_block (&se.pre, tmp);
1149 else
1151 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1153 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1154 3, gfc_build_addr_expr (NULL, tmp_stat),
1155 errmsg, errmsglen);
1156 gfc_add_expr_to_block (&se.pre, tmp);
1158 gfc_add_modify (&se.pre, stat,
1159 fold_convert (TREE_TYPE (stat), tmp_stat));
1162 else
1164 tree len;
1166 gcc_assert (type == EXEC_SYNC_IMAGES);
1168 if (!code->expr1)
1170 len = build_int_cst (integer_type_node, -1);
1171 images = null_pointer_node;
1173 else if (code->expr1->rank == 0)
1175 len = build_int_cst (integer_type_node, 1);
1176 images = gfc_build_addr_expr (NULL_TREE, images);
1178 else
1180 /* FIXME. */
1181 if (code->expr1->ts.kind != gfc_c_int_kind)
1182 gfc_fatal_error ("Sorry, only support for integer kind %d "
1183 "implemented for image-set at %L",
1184 gfc_c_int_kind, &code->expr1->where);
1186 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1187 images = se.expr;
1189 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1190 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1191 tmp = gfc_get_element_type (tmp);
1193 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1194 TREE_TYPE (len), len,
1195 fold_convert (TREE_TYPE (len),
1196 TYPE_SIZE_UNIT (tmp)));
1197 len = fold_convert (integer_type_node, len);
1200 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1201 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1203 If "stat" has the wrong integer type, use a temp variable of
1204 the right type and later cast the result back into "stat". */
1205 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1207 if (TREE_TYPE (stat) == integer_type_node)
1208 stat = gfc_build_addr_expr (NULL, stat);
1210 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1211 5, fold_convert (integer_type_node, len),
1212 images, stat, errmsg, errmsglen);
1213 gfc_add_expr_to_block (&se.pre, tmp);
1215 else
1217 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1219 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1220 5, fold_convert (integer_type_node, len),
1221 images, gfc_build_addr_expr (NULL, tmp_stat),
1222 errmsg, errmsglen);
1223 gfc_add_expr_to_block (&se.pre, tmp);
1225 gfc_add_modify (&se.pre, stat,
1226 fold_convert (TREE_TYPE (stat), tmp_stat));
1230 return gfc_finish_block (&se.pre);
1234 /* Generate GENERIC for the IF construct. This function also deals with
1235 the simple IF statement, because the front end translates the IF
1236 statement into an IF construct.
1238 We translate:
1240 IF (cond) THEN
1241 then_clause
1242 ELSEIF (cond2)
1243 elseif_clause
1244 ELSE
1245 else_clause
1246 ENDIF
1248 into:
1250 pre_cond_s;
1251 if (cond_s)
1253 then_clause;
1255 else
1257 pre_cond_s
1258 if (cond_s)
1260 elseif_clause
1262 else
1264 else_clause;
1268 where COND_S is the simplified version of the predicate. PRE_COND_S
1269 are the pre side-effects produced by the translation of the
1270 conditional.
1271 We need to build the chain recursively otherwise we run into
1272 problems with folding incomplete statements. */
1274 static tree
1275 gfc_trans_if_1 (gfc_code * code)
1277 gfc_se if_se;
1278 tree stmt, elsestmt;
1279 locus saved_loc;
1280 location_t loc;
1282 /* Check for an unconditional ELSE clause. */
1283 if (!code->expr1)
1284 return gfc_trans_code (code->next);
1286 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1287 gfc_init_se (&if_se, NULL);
1288 gfc_start_block (&if_se.pre);
1290 /* Calculate the IF condition expression. */
1291 if (code->expr1->where.lb)
1293 gfc_save_backend_locus (&saved_loc);
1294 gfc_set_backend_locus (&code->expr1->where);
1297 gfc_conv_expr_val (&if_se, code->expr1);
1299 if (code->expr1->where.lb)
1300 gfc_restore_backend_locus (&saved_loc);
1302 /* Translate the THEN clause. */
1303 stmt = gfc_trans_code (code->next);
1305 /* Translate the ELSE clause. */
1306 if (code->block)
1307 elsestmt = gfc_trans_if_1 (code->block);
1308 else
1309 elsestmt = build_empty_stmt (input_location);
1311 /* Build the condition expression and add it to the condition block. */
1312 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1313 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1314 elsestmt);
1316 gfc_add_expr_to_block (&if_se.pre, stmt);
1318 /* Finish off this statement. */
1319 return gfc_finish_block (&if_se.pre);
1322 tree
1323 gfc_trans_if (gfc_code * code)
1325 stmtblock_t body;
1326 tree exit_label;
1328 /* Create exit label so it is available for trans'ing the body code. */
1329 exit_label = gfc_build_label_decl (NULL_TREE);
1330 code->exit_label = exit_label;
1332 /* Translate the actual code in code->block. */
1333 gfc_init_block (&body);
1334 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1336 /* Add exit label. */
1337 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1339 return gfc_finish_block (&body);
1343 /* Translate an arithmetic IF expression.
1345 IF (cond) label1, label2, label3 translates to
1347 if (cond <= 0)
1349 if (cond < 0)
1350 goto label1;
1351 else // cond == 0
1352 goto label2;
1354 else // cond > 0
1355 goto label3;
1357 An optimized version can be generated in case of equal labels.
1358 E.g., if label1 is equal to label2, we can translate it to
1360 if (cond <= 0)
1361 goto label1;
1362 else
1363 goto label3;
1366 tree
1367 gfc_trans_arithmetic_if (gfc_code * code)
1369 gfc_se se;
1370 tree tmp;
1371 tree branch1;
1372 tree branch2;
1373 tree zero;
1375 /* Start a new block. */
1376 gfc_init_se (&se, NULL);
1377 gfc_start_block (&se.pre);
1379 /* Pre-evaluate COND. */
1380 gfc_conv_expr_val (&se, code->expr1);
1381 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1383 /* Build something to compare with. */
1384 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1386 if (code->label1->value != code->label2->value)
1388 /* If (cond < 0) take branch1 else take branch2.
1389 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1390 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1391 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1393 if (code->label1->value != code->label3->value)
1394 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1395 se.expr, zero);
1396 else
1397 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1398 se.expr, zero);
1400 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1401 tmp, branch1, branch2);
1403 else
1404 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1406 if (code->label1->value != code->label3->value
1407 && code->label2->value != code->label3->value)
1409 /* if (cond <= 0) take branch1 else take branch2. */
1410 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1411 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1412 se.expr, zero);
1413 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1414 tmp, branch1, branch2);
1417 /* Append the COND_EXPR to the evaluation of COND, and return. */
1418 gfc_add_expr_to_block (&se.pre, branch1);
1419 return gfc_finish_block (&se.pre);
1423 /* Translate a CRITICAL block. */
1424 tree
1425 gfc_trans_critical (gfc_code *code)
1427 stmtblock_t block;
1428 tree tmp, token = NULL_TREE;
1430 gfc_start_block (&block);
1432 if (flag_coarray == GFC_FCOARRAY_LIB)
1434 token = gfc_get_symbol_decl (code->resolved_sym);
1435 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1436 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1437 token, integer_zero_node, integer_one_node,
1438 null_pointer_node, null_pointer_node,
1439 null_pointer_node, integer_zero_node);
1440 gfc_add_expr_to_block (&block, tmp);
1442 /* It guarantees memory consistency within the same segment */
1443 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1444 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1445 gfc_build_string_const (1, ""),
1446 NULL_TREE, NULL_TREE,
1447 tree_cons (NULL_TREE, tmp, NULL_TREE),
1448 NULL_TREE);
1449 ASM_VOLATILE_P (tmp) = 1;
1451 gfc_add_expr_to_block (&block, tmp);
1454 tmp = gfc_trans_code (code->block->next);
1455 gfc_add_expr_to_block (&block, tmp);
1457 if (flag_coarray == GFC_FCOARRAY_LIB)
1459 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1460 token, integer_zero_node, integer_one_node,
1461 null_pointer_node, null_pointer_node,
1462 integer_zero_node);
1463 gfc_add_expr_to_block (&block, tmp);
1465 /* It guarantees memory consistency within the same segment */
1466 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1467 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1468 gfc_build_string_const (1, ""),
1469 NULL_TREE, NULL_TREE,
1470 tree_cons (NULL_TREE, tmp, NULL_TREE),
1471 NULL_TREE);
1472 ASM_VOLATILE_P (tmp) = 1;
1474 gfc_add_expr_to_block (&block, tmp);
1477 return gfc_finish_block (&block);
1481 /* Return true, when the class has a _len component. */
1483 static bool
1484 class_has_len_component (gfc_symbol *sym)
1486 gfc_component *comp = sym->ts.u.derived->components;
1487 while (comp)
1489 if (strcmp (comp->name, "_len") == 0)
1490 return true;
1491 comp = comp->next;
1493 return false;
1497 /* Do proper initialization for ASSOCIATE names. */
1499 static void
1500 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1502 gfc_expr *e;
1503 tree tmp;
1504 bool class_target;
1505 bool unlimited;
1506 tree desc;
1507 tree offset;
1508 tree dim;
1509 int n;
1510 tree charlen;
1511 bool need_len_assign;
1513 gcc_assert (sym->assoc);
1514 e = sym->assoc->target;
1516 class_target = (e->expr_type == EXPR_VARIABLE)
1517 && (gfc_is_class_scalar_expr (e)
1518 || gfc_is_class_array_ref (e, NULL));
1520 unlimited = UNLIMITED_POLY (e);
1522 /* Assignments to the string length need to be generated, when
1523 ( sym is a char array or
1524 sym has a _len component)
1525 and the associated expression is unlimited polymorphic, which is
1526 not (yet) correctly in 'unlimited', because for an already associated
1527 BT_DERIVED the u-poly flag is not set, i.e.,
1528 __tmp_CHARACTER_0_1 => w => arg
1529 ^ generated temp ^ from code, the w does not have the u-poly
1530 flag set, where UNLIMITED_POLY(e) expects it. */
1531 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1532 && e->ts.u.derived->attr.unlimited_polymorphic))
1533 && (sym->ts.type == BT_CHARACTER
1534 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1535 && class_has_len_component (sym))));
1536 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1537 to array temporary) for arrays with either unknown shape or if associating
1538 to a variable. */
1539 if (sym->attr.dimension && !class_target
1540 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1542 gfc_se se;
1543 tree desc;
1544 bool cst_array_ctor;
1546 desc = sym->backend_decl;
1547 cst_array_ctor = e->expr_type == EXPR_ARRAY
1548 && gfc_constant_array_constructor_p (e->value.constructor);
1550 /* If association is to an expression, evaluate it and create temporary.
1551 Otherwise, get descriptor of target for pointer assignment. */
1552 gfc_init_se (&se, NULL);
1553 if (sym->assoc->variable || cst_array_ctor)
1555 se.direct_byref = 1;
1556 se.use_offset = 1;
1557 se.expr = desc;
1560 gfc_conv_expr_descriptor (&se, e);
1562 /* If we didn't already do the pointer assignment, set associate-name
1563 descriptor to the one generated for the temporary. */
1564 if (!sym->assoc->variable && !cst_array_ctor)
1566 int dim;
1568 gfc_add_modify (&se.pre, desc, se.expr);
1570 /* The generated descriptor has lower bound zero (as array
1571 temporary), shift bounds so we get lower bounds of 1. */
1572 for (dim = 0; dim < e->rank; ++dim)
1573 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1574 dim, gfc_index_one_node);
1577 /* If this is a subreference array pointer associate name use the
1578 associate variable element size for the value of 'span'. */
1579 if (sym->attr.subref_array_pointer)
1581 gcc_assert (e->expr_type == EXPR_VARIABLE);
1582 tmp = e->symtree->n.sym->ts.type == BT_CLASS
1583 ? gfc_class_data_get (e->symtree->n.sym->backend_decl)
1584 : e->symtree->n.sym->backend_decl;
1585 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1586 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1587 gfc_add_modify (&se.pre, GFC_DECL_SPAN(desc), tmp);
1590 /* Done, register stuff as init / cleanup code. */
1591 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1592 gfc_finish_block (&se.post));
1595 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1596 arrays to be assigned directly. */
1597 else if (class_target && sym->attr.dimension
1598 && (sym->ts.type == BT_DERIVED || unlimited))
1600 gfc_se se;
1602 gfc_init_se (&se, NULL);
1603 se.descriptor_only = 1;
1604 /* In a select type the (temporary) associate variable shall point to
1605 a standard fortran array (lower bound == 1), but conv_expr ()
1606 just maps to the input array in the class object, whose lbound may
1607 be arbitrary. conv_expr_descriptor solves this by inserting a
1608 temporary array descriptor. */
1609 gfc_conv_expr_descriptor (&se, e);
1611 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1612 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1613 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1615 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1617 if (INDIRECT_REF_P (se.expr))
1618 tmp = TREE_OPERAND (se.expr, 0);
1619 else
1620 tmp = se.expr;
1622 gfc_add_modify (&se.pre, sym->backend_decl,
1623 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1625 else
1626 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1628 if (unlimited)
1630 /* Recover the dtype, which has been overwritten by the
1631 assignment from an unlimited polymorphic object. */
1632 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1633 gfc_add_modify (&se.pre, tmp,
1634 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1637 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1638 gfc_finish_block (&se.post));
1641 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1642 else if (gfc_is_associate_pointer (sym))
1644 gfc_se se;
1646 gcc_assert (!sym->attr.dimension);
1648 gfc_init_se (&se, NULL);
1650 /* Class associate-names come this way because they are
1651 unconditionally associate pointers and the symbol is scalar. */
1652 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1654 tree target_expr;
1655 /* For a class array we need a descriptor for the selector. */
1656 gfc_conv_expr_descriptor (&se, e);
1657 /* Needed to get/set the _len component below. */
1658 target_expr = se.expr;
1660 /* Obtain a temporary class container for the result. */
1661 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1662 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1664 /* Set the offset. */
1665 desc = gfc_class_data_get (se.expr);
1666 offset = gfc_index_zero_node;
1667 for (n = 0; n < e->rank; n++)
1669 dim = gfc_rank_cst[n];
1670 tmp = fold_build2_loc (input_location, MULT_EXPR,
1671 gfc_array_index_type,
1672 gfc_conv_descriptor_stride_get (desc, dim),
1673 gfc_conv_descriptor_lbound_get (desc, dim));
1674 offset = fold_build2_loc (input_location, MINUS_EXPR,
1675 gfc_array_index_type,
1676 offset, tmp);
1678 if (need_len_assign)
1680 if (e->symtree
1681 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1682 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1683 /* Use the original class descriptor stored in the saved
1684 descriptor to get the target_expr. */
1685 target_expr =
1686 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1687 else
1688 /* Strip the _data component from the target_expr. */
1689 target_expr = TREE_OPERAND (target_expr, 0);
1690 /* Add a reference to the _len comp to the target expr. */
1691 tmp = gfc_class_len_get (target_expr);
1692 /* Get the component-ref for the temp structure's _len comp. */
1693 charlen = gfc_class_len_get (se.expr);
1694 /* Add the assign to the beginning of the block... */
1695 gfc_add_modify (&se.pre, charlen,
1696 fold_convert (TREE_TYPE (charlen), tmp));
1697 /* and the oposite way at the end of the block, to hand changes
1698 on the string length back. */
1699 gfc_add_modify (&se.post, tmp,
1700 fold_convert (TREE_TYPE (tmp), charlen));
1701 /* Length assignment done, prevent adding it again below. */
1702 need_len_assign = false;
1704 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1706 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1707 && CLASS_DATA (e)->attr.dimension)
1709 /* This is bound to be a class array element. */
1710 gfc_conv_expr_reference (&se, e);
1711 /* Get the _vptr component of the class object. */
1712 tmp = gfc_get_vptr_from_expr (se.expr);
1713 /* Obtain a temporary class container for the result. */
1714 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1715 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1717 else
1719 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1720 which has the string length included. For CHARACTERS it is still
1721 needed and will be done at the end of this routine. */
1722 gfc_conv_expr (&se, e);
1723 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1726 tmp = TREE_TYPE (sym->backend_decl);
1727 tmp = gfc_build_addr_expr (tmp, se.expr);
1728 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1730 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1731 gfc_finish_block (&se.post));
1734 /* Do a simple assignment. This is for scalar expressions, where we
1735 can simply use expression assignment. */
1736 else
1738 gfc_expr *lhs;
1740 lhs = gfc_lval_expr_from_sym (sym);
1741 tmp = gfc_trans_assignment (lhs, e, false, true);
1742 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1745 /* Set the stringlength, when needed. */
1746 if (need_len_assign)
1748 gfc_se se;
1749 gfc_init_se (&se, NULL);
1750 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1752 /* What about deferred strings? */
1753 gcc_assert (!e->symtree->n.sym->ts.deferred);
1754 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1756 else
1757 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1758 gfc_get_symbol_decl (sym);
1759 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1760 : gfc_class_len_get (sym->backend_decl);
1761 /* Prevent adding a noop len= len. */
1762 if (tmp != charlen)
1764 gfc_add_modify (&se.pre, charlen,
1765 fold_convert (TREE_TYPE (charlen), tmp));
1766 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1767 gfc_finish_block (&se.post));
1773 /* Translate a BLOCK construct. This is basically what we would do for a
1774 procedure body. */
1776 tree
1777 gfc_trans_block_construct (gfc_code* code)
1779 gfc_namespace* ns;
1780 gfc_symbol* sym;
1781 gfc_wrapped_block block;
1782 tree exit_label;
1783 stmtblock_t body;
1784 gfc_association_list *ass;
1786 ns = code->ext.block.ns;
1787 gcc_assert (ns);
1788 sym = ns->proc_name;
1789 gcc_assert (sym);
1791 /* Process local variables. */
1792 gcc_assert (!sym->tlink);
1793 sym->tlink = sym;
1794 gfc_process_block_locals (ns);
1796 /* Generate code including exit-label. */
1797 gfc_init_block (&body);
1798 exit_label = gfc_build_label_decl (NULL_TREE);
1799 code->exit_label = exit_label;
1801 finish_oacc_declare (ns, sym, true);
1803 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1804 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1806 /* Finish everything. */
1807 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1808 gfc_trans_deferred_vars (sym, &block);
1809 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1810 trans_associate_var (ass->st->n.sym, &block);
1812 return gfc_finish_wrapped_block (&block);
1815 /* Translate the simple DO construct in a C-style manner.
1816 This is where the loop variable has integer type and step +-1.
1817 Following code will generate infinite loop in case where TO is INT_MAX
1818 (for +1 step) or INT_MIN (for -1 step)
1820 We translate a do loop from:
1822 DO dovar = from, to, step
1823 body
1824 END DO
1828 [Evaluate loop bounds and step]
1829 dovar = from;
1830 for (;;)
1832 if (dovar > to)
1833 goto end_label;
1834 body;
1835 cycle_label:
1836 dovar += step;
1838 end_label:
1840 This helps the optimizers by avoiding the extra pre-header condition and
1841 we save a register as we just compare the updated IV (not a value in
1842 previous step). */
1844 static tree
1845 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1846 tree from, tree to, tree step, tree exit_cond)
1848 stmtblock_t body;
1849 tree type;
1850 tree cond;
1851 tree tmp;
1852 tree saved_dovar = NULL;
1853 tree cycle_label;
1854 tree exit_label;
1855 location_t loc;
1856 type = TREE_TYPE (dovar);
1857 bool is_step_positive = tree_int_cst_sgn (step) > 0;
1859 loc = code->ext.iterator->start->where.lb->location;
1861 /* Initialize the DO variable: dovar = from. */
1862 gfc_add_modify_loc (loc, pblock, dovar,
1863 fold_convert (TREE_TYPE (dovar), from));
1865 /* Save value for do-tinkering checking. */
1866 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1868 saved_dovar = gfc_create_var (type, ".saved_dovar");
1869 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1872 /* Cycle and exit statements are implemented with gotos. */
1873 cycle_label = gfc_build_label_decl (NULL_TREE);
1874 exit_label = gfc_build_label_decl (NULL_TREE);
1876 /* Put the labels where they can be found later. See gfc_trans_do(). */
1877 code->cycle_label = cycle_label;
1878 code->exit_label = exit_label;
1880 /* Loop body. */
1881 gfc_start_block (&body);
1883 /* Exit the loop if there is an I/O result condition or error. */
1884 if (exit_cond)
1886 tmp = build1_v (GOTO_EXPR, exit_label);
1887 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1888 exit_cond, tmp,
1889 build_empty_stmt (loc));
1890 gfc_add_expr_to_block (&body, tmp);
1893 /* Evaluate the loop condition. */
1894 if (is_step_positive)
1895 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, dovar,
1896 fold_convert (type, to));
1897 else
1898 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, dovar,
1899 fold_convert (type, to));
1901 cond = gfc_evaluate_now_loc (loc, cond, &body);
1903 /* The loop exit. */
1904 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1905 TREE_USED (exit_label) = 1;
1906 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1907 cond, tmp, build_empty_stmt (loc));
1908 gfc_add_expr_to_block (&body, tmp);
1910 /* Check whether the induction variable is equal to INT_MAX
1911 (respectively to INT_MIN). */
1912 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1914 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
1915 : TYPE_MIN_VALUE (type);
1917 tmp = fold_build2_loc (loc, EQ_EXPR, boolean_type_node,
1918 dovar, boundary);
1919 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1920 "Loop iterates infinitely");
1923 /* Main loop body. */
1924 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1925 gfc_add_expr_to_block (&body, tmp);
1927 /* Label for cycle statements (if needed). */
1928 if (TREE_USED (cycle_label))
1930 tmp = build1_v (LABEL_EXPR, cycle_label);
1931 gfc_add_expr_to_block (&body, tmp);
1934 /* Check whether someone has modified the loop variable. */
1935 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1937 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1938 dovar, saved_dovar);
1939 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1940 "Loop variable has been modified");
1943 /* Increment the loop variable. */
1944 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1945 gfc_add_modify_loc (loc, &body, dovar, tmp);
1947 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1948 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1950 /* Finish the loop body. */
1951 tmp = gfc_finish_block (&body);
1952 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1954 gfc_add_expr_to_block (pblock, tmp);
1956 /* Add the exit label. */
1957 tmp = build1_v (LABEL_EXPR, exit_label);
1958 gfc_add_expr_to_block (pblock, tmp);
1960 return gfc_finish_block (pblock);
1963 /* Translate the DO construct. This obviously is one of the most
1964 important ones to get right with any compiler, but especially
1965 so for Fortran.
1967 We special case some loop forms as described in gfc_trans_simple_do.
1968 For other cases we implement them with a separate loop count,
1969 as described in the standard.
1971 We translate a do loop from:
1973 DO dovar = from, to, step
1974 body
1975 END DO
1979 [evaluate loop bounds and step]
1980 empty = (step > 0 ? to < from : to > from);
1981 countm1 = (to - from) / step;
1982 dovar = from;
1983 if (empty) goto exit_label;
1984 for (;;)
1986 body;
1987 cycle_label:
1988 dovar += step
1989 countm1t = countm1;
1990 countm1--;
1991 if (countm1t == 0) goto exit_label;
1993 exit_label:
1995 countm1 is an unsigned integer. It is equal to the loop count minus one,
1996 because the loop count itself can overflow. */
1998 tree
1999 gfc_trans_do (gfc_code * code, tree exit_cond)
2001 gfc_se se;
2002 tree dovar;
2003 tree saved_dovar = NULL;
2004 tree from;
2005 tree to;
2006 tree step;
2007 tree countm1;
2008 tree type;
2009 tree utype;
2010 tree cond;
2011 tree cycle_label;
2012 tree exit_label;
2013 tree tmp;
2014 stmtblock_t block;
2015 stmtblock_t body;
2016 location_t loc;
2018 gfc_start_block (&block);
2020 loc = code->ext.iterator->start->where.lb->location;
2022 /* Evaluate all the expressions in the iterator. */
2023 gfc_init_se (&se, NULL);
2024 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2025 gfc_add_block_to_block (&block, &se.pre);
2026 dovar = se.expr;
2027 type = TREE_TYPE (dovar);
2029 gfc_init_se (&se, NULL);
2030 gfc_conv_expr_val (&se, code->ext.iterator->start);
2031 gfc_add_block_to_block (&block, &se.pre);
2032 from = gfc_evaluate_now (se.expr, &block);
2034 gfc_init_se (&se, NULL);
2035 gfc_conv_expr_val (&se, code->ext.iterator->end);
2036 gfc_add_block_to_block (&block, &se.pre);
2037 to = gfc_evaluate_now (se.expr, &block);
2039 gfc_init_se (&se, NULL);
2040 gfc_conv_expr_val (&se, code->ext.iterator->step);
2041 gfc_add_block_to_block (&block, &se.pre);
2042 step = gfc_evaluate_now (se.expr, &block);
2044 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2046 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
2047 build_zero_cst (type));
2048 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2049 "DO step value is zero");
2052 /* Special case simple loops. */
2053 if (TREE_CODE (type) == INTEGER_TYPE
2054 && (integer_onep (step)
2055 || tree_int_cst_equal (step, integer_minus_one_node)))
2056 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2057 exit_cond);
2059 if (TREE_CODE (type) == INTEGER_TYPE)
2060 utype = unsigned_type_for (type);
2061 else
2062 utype = unsigned_type_for (gfc_array_index_type);
2063 countm1 = gfc_create_var (utype, "countm1");
2065 /* Cycle and exit statements are implemented with gotos. */
2066 cycle_label = gfc_build_label_decl (NULL_TREE);
2067 exit_label = gfc_build_label_decl (NULL_TREE);
2068 TREE_USED (exit_label) = 1;
2070 /* Put these labels where they can be found later. */
2071 code->cycle_label = cycle_label;
2072 code->exit_label = exit_label;
2074 /* Initialize the DO variable: dovar = from. */
2075 gfc_add_modify (&block, dovar, from);
2077 /* Save value for do-tinkering checking. */
2078 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2080 saved_dovar = gfc_create_var (type, ".saved_dovar");
2081 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2084 /* Initialize loop count and jump to exit label if the loop is empty.
2085 This code is executed before we enter the loop body. We generate:
2086 if (step > 0)
2088 countm1 = (to - from) / step;
2089 if (to < from)
2090 goto exit_label;
2092 else
2094 countm1 = (from - to) / -step;
2095 if (to > from)
2096 goto exit_label;
2100 if (TREE_CODE (type) == INTEGER_TYPE)
2102 tree pos, neg, tou, fromu, stepu, tmp2;
2104 /* The distance from FROM to TO cannot always be represented in a signed
2105 type, thus use unsigned arithmetic, also to avoid any undefined
2106 overflow issues. */
2107 tou = fold_convert (utype, to);
2108 fromu = fold_convert (utype, from);
2109 stepu = fold_convert (utype, step);
2111 /* For a positive step, when to < from, exit, otherwise compute
2112 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2113 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
2114 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2115 fold_build2_loc (loc, MINUS_EXPR, utype,
2116 tou, fromu),
2117 stepu);
2118 pos = build2 (COMPOUND_EXPR, void_type_node,
2119 fold_build2 (MODIFY_EXPR, void_type_node,
2120 countm1, tmp2),
2121 build3_loc (loc, COND_EXPR, void_type_node,
2122 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2123 build1_loc (loc, GOTO_EXPR, void_type_node,
2124 exit_label), NULL_TREE));
2126 /* For a negative step, when to > from, exit, otherwise compute
2127 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2128 tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, to, from);
2129 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2130 fold_build2_loc (loc, MINUS_EXPR, utype,
2131 fromu, tou),
2132 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2133 neg = build2 (COMPOUND_EXPR, void_type_node,
2134 fold_build2 (MODIFY_EXPR, void_type_node,
2135 countm1, tmp2),
2136 build3_loc (loc, COND_EXPR, void_type_node,
2137 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2138 build1_loc (loc, GOTO_EXPR, void_type_node,
2139 exit_label), NULL_TREE));
2141 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
2142 build_int_cst (TREE_TYPE (step), 0));
2143 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2145 gfc_add_expr_to_block (&block, tmp);
2147 else
2149 tree pos_step;
2151 /* TODO: We could use the same width as the real type.
2152 This would probably cause more problems that it solves
2153 when we implement "long double" types. */
2155 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2156 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2157 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2158 gfc_add_modify (&block, countm1, tmp);
2160 /* We need a special check for empty loops:
2161 empty = (step > 0 ? to < from : to > from); */
2162 pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
2163 build_zero_cst (type));
2164 tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
2165 fold_build2_loc (loc, LT_EXPR,
2166 boolean_type_node, to, from),
2167 fold_build2_loc (loc, GT_EXPR,
2168 boolean_type_node, to, from));
2169 /* If the loop is empty, go directly to the exit label. */
2170 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2171 build1_v (GOTO_EXPR, exit_label),
2172 build_empty_stmt (input_location));
2173 gfc_add_expr_to_block (&block, tmp);
2176 /* Loop body. */
2177 gfc_start_block (&body);
2179 /* Main loop body. */
2180 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2181 gfc_add_expr_to_block (&body, tmp);
2183 /* Label for cycle statements (if needed). */
2184 if (TREE_USED (cycle_label))
2186 tmp = build1_v (LABEL_EXPR, cycle_label);
2187 gfc_add_expr_to_block (&body, tmp);
2190 /* Check whether someone has modified the loop variable. */
2191 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2193 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
2194 saved_dovar);
2195 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2196 "Loop variable has been modified");
2199 /* Exit the loop if there is an I/O result condition or error. */
2200 if (exit_cond)
2202 tmp = build1_v (GOTO_EXPR, exit_label);
2203 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2204 exit_cond, tmp,
2205 build_empty_stmt (input_location));
2206 gfc_add_expr_to_block (&body, tmp);
2209 /* Increment the loop variable. */
2210 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2211 gfc_add_modify_loc (loc, &body, dovar, tmp);
2213 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2214 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2216 /* Initialize countm1t. */
2217 tree countm1t = gfc_create_var (utype, "countm1t");
2218 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2220 /* Decrement the loop count. */
2221 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2222 build_int_cst (utype, 1));
2223 gfc_add_modify_loc (loc, &body, countm1, tmp);
2225 /* End with the loop condition. Loop until countm1t == 0. */
2226 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, countm1t,
2227 build_int_cst (utype, 0));
2228 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2229 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2230 cond, tmp, build_empty_stmt (loc));
2231 gfc_add_expr_to_block (&body, tmp);
2233 /* End of loop body. */
2234 tmp = gfc_finish_block (&body);
2236 /* The for loop itself. */
2237 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2238 gfc_add_expr_to_block (&block, tmp);
2240 /* Add the exit label. */
2241 tmp = build1_v (LABEL_EXPR, exit_label);
2242 gfc_add_expr_to_block (&block, tmp);
2244 return gfc_finish_block (&block);
2248 /* Translate the DO WHILE construct.
2250 We translate
2252 DO WHILE (cond)
2253 body
2254 END DO
2258 for ( ; ; )
2260 pre_cond;
2261 if (! cond) goto exit_label;
2262 body;
2263 cycle_label:
2265 exit_label:
2267 Because the evaluation of the exit condition `cond' may have side
2268 effects, we can't do much for empty loop bodies. The backend optimizers
2269 should be smart enough to eliminate any dead loops. */
2271 tree
2272 gfc_trans_do_while (gfc_code * code)
2274 gfc_se cond;
2275 tree tmp;
2276 tree cycle_label;
2277 tree exit_label;
2278 stmtblock_t block;
2280 /* Everything we build here is part of the loop body. */
2281 gfc_start_block (&block);
2283 /* Cycle and exit statements are implemented with gotos. */
2284 cycle_label = gfc_build_label_decl (NULL_TREE);
2285 exit_label = gfc_build_label_decl (NULL_TREE);
2287 /* Put the labels where they can be found later. See gfc_trans_do(). */
2288 code->cycle_label = cycle_label;
2289 code->exit_label = exit_label;
2291 /* Create a GIMPLE version of the exit condition. */
2292 gfc_init_se (&cond, NULL);
2293 gfc_conv_expr_val (&cond, code->expr1);
2294 gfc_add_block_to_block (&block, &cond.pre);
2295 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2296 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2298 /* Build "IF (! cond) GOTO exit_label". */
2299 tmp = build1_v (GOTO_EXPR, exit_label);
2300 TREE_USED (exit_label) = 1;
2301 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2302 void_type_node, cond.expr, tmp,
2303 build_empty_stmt (code->expr1->where.lb->location));
2304 gfc_add_expr_to_block (&block, tmp);
2306 /* The main body of the loop. */
2307 tmp = gfc_trans_code (code->block->next);
2308 gfc_add_expr_to_block (&block, tmp);
2310 /* Label for cycle statements (if needed). */
2311 if (TREE_USED (cycle_label))
2313 tmp = build1_v (LABEL_EXPR, cycle_label);
2314 gfc_add_expr_to_block (&block, tmp);
2317 /* End of loop body. */
2318 tmp = gfc_finish_block (&block);
2320 gfc_init_block (&block);
2321 /* Build the loop. */
2322 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2323 void_type_node, tmp);
2324 gfc_add_expr_to_block (&block, tmp);
2326 /* Add the exit label. */
2327 tmp = build1_v (LABEL_EXPR, exit_label);
2328 gfc_add_expr_to_block (&block, tmp);
2330 return gfc_finish_block (&block);
2334 /* Deal with the particular case of SELECT_TYPE, where the vtable
2335 addresses are used for the selection. Since these are not sorted,
2336 the selection has to be made by a series of if statements. */
2338 static tree
2339 gfc_trans_select_type_cases (gfc_code * code)
2341 gfc_code *c;
2342 gfc_case *cp;
2343 tree tmp;
2344 tree cond;
2345 tree low;
2346 tree high;
2347 gfc_se se;
2348 gfc_se cse;
2349 stmtblock_t block;
2350 stmtblock_t body;
2351 bool def = false;
2352 gfc_expr *e;
2353 gfc_start_block (&block);
2355 /* Calculate the switch expression. */
2356 gfc_init_se (&se, NULL);
2357 gfc_conv_expr_val (&se, code->expr1);
2358 gfc_add_block_to_block (&block, &se.pre);
2360 /* Generate an expression for the selector hash value, for
2361 use to resolve character cases. */
2362 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2363 gfc_add_hash_component (e);
2365 TREE_USED (code->exit_label) = 0;
2367 repeat:
2368 for (c = code->block; c; c = c->block)
2370 cp = c->ext.block.case_list;
2372 /* Assume it's the default case. */
2373 low = NULL_TREE;
2374 high = NULL_TREE;
2375 tmp = NULL_TREE;
2377 /* Put the default case at the end. */
2378 if ((!def && !cp->low) || (def && cp->low))
2379 continue;
2381 if (cp->low && (cp->ts.type == BT_CLASS
2382 || cp->ts.type == BT_DERIVED))
2384 gfc_init_se (&cse, NULL);
2385 gfc_conv_expr_val (&cse, cp->low);
2386 gfc_add_block_to_block (&block, &cse.pre);
2387 low = cse.expr;
2389 else if (cp->ts.type != BT_UNKNOWN)
2391 gcc_assert (cp->high);
2392 gfc_init_se (&cse, NULL);
2393 gfc_conv_expr_val (&cse, cp->high);
2394 gfc_add_block_to_block (&block, &cse.pre);
2395 high = cse.expr;
2398 gfc_init_block (&body);
2400 /* Add the statements for this case. */
2401 tmp = gfc_trans_code (c->next);
2402 gfc_add_expr_to_block (&body, tmp);
2404 /* Break to the end of the SELECT TYPE construct. The default
2405 case just falls through. */
2406 if (!def)
2408 TREE_USED (code->exit_label) = 1;
2409 tmp = build1_v (GOTO_EXPR, code->exit_label);
2410 gfc_add_expr_to_block (&body, tmp);
2413 tmp = gfc_finish_block (&body);
2415 if (low != NULL_TREE)
2417 /* Compare vtable pointers. */
2418 cond = fold_build2_loc (input_location, EQ_EXPR,
2419 TREE_TYPE (se.expr), se.expr, low);
2420 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2421 cond, tmp,
2422 build_empty_stmt (input_location));
2424 else if (high != NULL_TREE)
2426 /* Compare hash values for character cases. */
2427 gfc_init_se (&cse, NULL);
2428 gfc_conv_expr_val (&cse, e);
2429 gfc_add_block_to_block (&block, &cse.pre);
2431 cond = fold_build2_loc (input_location, EQ_EXPR,
2432 TREE_TYPE (se.expr), high, cse.expr);
2433 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2434 cond, tmp,
2435 build_empty_stmt (input_location));
2438 gfc_add_expr_to_block (&block, tmp);
2441 if (!def)
2443 def = true;
2444 goto repeat;
2447 gfc_free_expr (e);
2449 return gfc_finish_block (&block);
2453 /* Translate the SELECT CASE construct for INTEGER case expressions,
2454 without killing all potential optimizations. The problem is that
2455 Fortran allows unbounded cases, but the back-end does not, so we
2456 need to intercept those before we enter the equivalent SWITCH_EXPR
2457 we can build.
2459 For example, we translate this,
2461 SELECT CASE (expr)
2462 CASE (:100,101,105:115)
2463 block_1
2464 CASE (190:199,200:)
2465 block_2
2466 CASE (300)
2467 block_3
2468 CASE DEFAULT
2469 block_4
2470 END SELECT
2472 to the GENERIC equivalent,
2474 switch (expr)
2476 case (minimum value for typeof(expr) ... 100:
2477 case 101:
2478 case 105 ... 114:
2479 block1:
2480 goto end_label;
2482 case 200 ... (maximum value for typeof(expr):
2483 case 190 ... 199:
2484 block2;
2485 goto end_label;
2487 case 300:
2488 block_3;
2489 goto end_label;
2491 default:
2492 block_4;
2493 goto end_label;
2496 end_label: */
2498 static tree
2499 gfc_trans_integer_select (gfc_code * code)
2501 gfc_code *c;
2502 gfc_case *cp;
2503 tree end_label;
2504 tree tmp;
2505 gfc_se se;
2506 stmtblock_t block;
2507 stmtblock_t body;
2509 gfc_start_block (&block);
2511 /* Calculate the switch expression. */
2512 gfc_init_se (&se, NULL);
2513 gfc_conv_expr_val (&se, code->expr1);
2514 gfc_add_block_to_block (&block, &se.pre);
2516 end_label = gfc_build_label_decl (NULL_TREE);
2518 gfc_init_block (&body);
2520 for (c = code->block; c; c = c->block)
2522 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2524 tree low, high;
2525 tree label;
2527 /* Assume it's the default case. */
2528 low = high = NULL_TREE;
2530 if (cp->low)
2532 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2533 cp->low->ts.kind);
2535 /* If there's only a lower bound, set the high bound to the
2536 maximum value of the case expression. */
2537 if (!cp->high)
2538 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2541 if (cp->high)
2543 /* Three cases are possible here:
2545 1) There is no lower bound, e.g. CASE (:N).
2546 2) There is a lower bound .NE. high bound, that is
2547 a case range, e.g. CASE (N:M) where M>N (we make
2548 sure that M>N during type resolution).
2549 3) There is a lower bound, and it has the same value
2550 as the high bound, e.g. CASE (N:N). This is our
2551 internal representation of CASE(N).
2553 In the first and second case, we need to set a value for
2554 high. In the third case, we don't because the GCC middle
2555 end represents a single case value by just letting high be
2556 a NULL_TREE. We can't do that because we need to be able
2557 to represent unbounded cases. */
2559 if (!cp->low
2560 || (cp->low
2561 && mpz_cmp (cp->low->value.integer,
2562 cp->high->value.integer) != 0))
2563 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2564 cp->high->ts.kind);
2566 /* Unbounded case. */
2567 if (!cp->low)
2568 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2571 /* Build a label. */
2572 label = gfc_build_label_decl (NULL_TREE);
2574 /* Add this case label.
2575 Add parameter 'label', make it match GCC backend. */
2576 tmp = build_case_label (low, high, label);
2577 gfc_add_expr_to_block (&body, tmp);
2580 /* Add the statements for this case. */
2581 tmp = gfc_trans_code (c->next);
2582 gfc_add_expr_to_block (&body, tmp);
2584 /* Break to the end of the construct. */
2585 tmp = build1_v (GOTO_EXPR, end_label);
2586 gfc_add_expr_to_block (&body, tmp);
2589 tmp = gfc_finish_block (&body);
2590 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2591 se.expr, tmp, NULL_TREE);
2592 gfc_add_expr_to_block (&block, tmp);
2594 tmp = build1_v (LABEL_EXPR, end_label);
2595 gfc_add_expr_to_block (&block, tmp);
2597 return gfc_finish_block (&block);
2601 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2603 There are only two cases possible here, even though the standard
2604 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2605 .FALSE., and DEFAULT.
2607 We never generate more than two blocks here. Instead, we always
2608 try to eliminate the DEFAULT case. This way, we can translate this
2609 kind of SELECT construct to a simple
2611 if {} else {};
2613 expression in GENERIC. */
2615 static tree
2616 gfc_trans_logical_select (gfc_code * code)
2618 gfc_code *c;
2619 gfc_code *t, *f, *d;
2620 gfc_case *cp;
2621 gfc_se se;
2622 stmtblock_t block;
2624 /* Assume we don't have any cases at all. */
2625 t = f = d = NULL;
2627 /* Now see which ones we actually do have. We can have at most two
2628 cases in a single case list: one for .TRUE. and one for .FALSE.
2629 The default case is always separate. If the cases for .TRUE. and
2630 .FALSE. are in the same case list, the block for that case list
2631 always executed, and we don't generate code a COND_EXPR. */
2632 for (c = code->block; c; c = c->block)
2634 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2636 if (cp->low)
2638 if (cp->low->value.logical == 0) /* .FALSE. */
2639 f = c;
2640 else /* if (cp->value.logical != 0), thus .TRUE. */
2641 t = c;
2643 else
2644 d = c;
2648 /* Start a new block. */
2649 gfc_start_block (&block);
2651 /* Calculate the switch expression. We always need to do this
2652 because it may have side effects. */
2653 gfc_init_se (&se, NULL);
2654 gfc_conv_expr_val (&se, code->expr1);
2655 gfc_add_block_to_block (&block, &se.pre);
2657 if (t == f && t != NULL)
2659 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2660 translate the code for these cases, append it to the current
2661 block. */
2662 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2664 else
2666 tree true_tree, false_tree, stmt;
2668 true_tree = build_empty_stmt (input_location);
2669 false_tree = build_empty_stmt (input_location);
2671 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2672 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2673 make the missing case the default case. */
2674 if (t != NULL && f != NULL)
2675 d = NULL;
2676 else if (d != NULL)
2678 if (t == NULL)
2679 t = d;
2680 else
2681 f = d;
2684 /* Translate the code for each of these blocks, and append it to
2685 the current block. */
2686 if (t != NULL)
2687 true_tree = gfc_trans_code (t->next);
2689 if (f != NULL)
2690 false_tree = gfc_trans_code (f->next);
2692 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2693 se.expr, true_tree, false_tree);
2694 gfc_add_expr_to_block (&block, stmt);
2697 return gfc_finish_block (&block);
2701 /* The jump table types are stored in static variables to avoid
2702 constructing them from scratch every single time. */
2703 static GTY(()) tree select_struct[2];
2705 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2706 Instead of generating compares and jumps, it is far simpler to
2707 generate a data structure describing the cases in order and call a
2708 library subroutine that locates the right case.
2709 This is particularly true because this is the only case where we
2710 might have to dispose of a temporary.
2711 The library subroutine returns a pointer to jump to or NULL if no
2712 branches are to be taken. */
2714 static tree
2715 gfc_trans_character_select (gfc_code *code)
2717 tree init, end_label, tmp, type, case_num, label, fndecl;
2718 stmtblock_t block, body;
2719 gfc_case *cp, *d;
2720 gfc_code *c;
2721 gfc_se se, expr1se;
2722 int n, k;
2723 vec<constructor_elt, va_gc> *inits = NULL;
2725 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2727 /* The jump table types are stored in static variables to avoid
2728 constructing them from scratch every single time. */
2729 static tree ss_string1[2], ss_string1_len[2];
2730 static tree ss_string2[2], ss_string2_len[2];
2731 static tree ss_target[2];
2733 cp = code->block->ext.block.case_list;
2734 while (cp->left != NULL)
2735 cp = cp->left;
2737 /* Generate the body */
2738 gfc_start_block (&block);
2739 gfc_init_se (&expr1se, NULL);
2740 gfc_conv_expr_reference (&expr1se, code->expr1);
2742 gfc_add_block_to_block (&block, &expr1se.pre);
2744 end_label = gfc_build_label_decl (NULL_TREE);
2746 gfc_init_block (&body);
2748 /* Attempt to optimize length 1 selects. */
2749 if (integer_onep (expr1se.string_length))
2751 for (d = cp; d; d = d->right)
2753 int i;
2754 if (d->low)
2756 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2757 && d->low->ts.type == BT_CHARACTER);
2758 if (d->low->value.character.length > 1)
2760 for (i = 1; i < d->low->value.character.length; i++)
2761 if (d->low->value.character.string[i] != ' ')
2762 break;
2763 if (i != d->low->value.character.length)
2765 if (optimize && d->high && i == 1)
2767 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2768 && d->high->ts.type == BT_CHARACTER);
2769 if (d->high->value.character.length > 1
2770 && (d->low->value.character.string[0]
2771 == d->high->value.character.string[0])
2772 && d->high->value.character.string[1] != ' '
2773 && ((d->low->value.character.string[1] < ' ')
2774 == (d->high->value.character.string[1]
2775 < ' ')))
2776 continue;
2778 break;
2782 if (d->high)
2784 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2785 && d->high->ts.type == BT_CHARACTER);
2786 if (d->high->value.character.length > 1)
2788 for (i = 1; i < d->high->value.character.length; i++)
2789 if (d->high->value.character.string[i] != ' ')
2790 break;
2791 if (i != d->high->value.character.length)
2792 break;
2796 if (d == NULL)
2798 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2800 for (c = code->block; c; c = c->block)
2802 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2804 tree low, high;
2805 tree label;
2806 gfc_char_t r;
2808 /* Assume it's the default case. */
2809 low = high = NULL_TREE;
2811 if (cp->low)
2813 /* CASE ('ab') or CASE ('ab':'az') will never match
2814 any length 1 character. */
2815 if (cp->low->value.character.length > 1
2816 && cp->low->value.character.string[1] != ' ')
2817 continue;
2819 if (cp->low->value.character.length > 0)
2820 r = cp->low->value.character.string[0];
2821 else
2822 r = ' ';
2823 low = build_int_cst (ctype, r);
2825 /* If there's only a lower bound, set the high bound
2826 to the maximum value of the case expression. */
2827 if (!cp->high)
2828 high = TYPE_MAX_VALUE (ctype);
2831 if (cp->high)
2833 if (!cp->low
2834 || (cp->low->value.character.string[0]
2835 != cp->high->value.character.string[0]))
2837 if (cp->high->value.character.length > 0)
2838 r = cp->high->value.character.string[0];
2839 else
2840 r = ' ';
2841 high = build_int_cst (ctype, r);
2844 /* Unbounded case. */
2845 if (!cp->low)
2846 low = TYPE_MIN_VALUE (ctype);
2849 /* Build a label. */
2850 label = gfc_build_label_decl (NULL_TREE);
2852 /* Add this case label.
2853 Add parameter 'label', make it match GCC backend. */
2854 tmp = build_case_label (low, high, label);
2855 gfc_add_expr_to_block (&body, tmp);
2858 /* Add the statements for this case. */
2859 tmp = gfc_trans_code (c->next);
2860 gfc_add_expr_to_block (&body, tmp);
2862 /* Break to the end of the construct. */
2863 tmp = build1_v (GOTO_EXPR, end_label);
2864 gfc_add_expr_to_block (&body, tmp);
2867 tmp = gfc_string_to_single_character (expr1se.string_length,
2868 expr1se.expr,
2869 code->expr1->ts.kind);
2870 case_num = gfc_create_var (ctype, "case_num");
2871 gfc_add_modify (&block, case_num, tmp);
2873 gfc_add_block_to_block (&block, &expr1se.post);
2875 tmp = gfc_finish_block (&body);
2876 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2877 case_num, tmp, NULL_TREE);
2878 gfc_add_expr_to_block (&block, tmp);
2880 tmp = build1_v (LABEL_EXPR, end_label);
2881 gfc_add_expr_to_block (&block, tmp);
2883 return gfc_finish_block (&block);
2887 if (code->expr1->ts.kind == 1)
2888 k = 0;
2889 else if (code->expr1->ts.kind == 4)
2890 k = 1;
2891 else
2892 gcc_unreachable ();
2894 if (select_struct[k] == NULL)
2896 tree *chain = NULL;
2897 select_struct[k] = make_node (RECORD_TYPE);
2899 if (code->expr1->ts.kind == 1)
2900 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2901 else if (code->expr1->ts.kind == 4)
2902 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2903 else
2904 gcc_unreachable ();
2906 #undef ADD_FIELD
2907 #define ADD_FIELD(NAME, TYPE) \
2908 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2909 get_identifier (stringize(NAME)), \
2910 TYPE, \
2911 &chain)
2913 ADD_FIELD (string1, pchartype);
2914 ADD_FIELD (string1_len, gfc_charlen_type_node);
2916 ADD_FIELD (string2, pchartype);
2917 ADD_FIELD (string2_len, gfc_charlen_type_node);
2919 ADD_FIELD (target, integer_type_node);
2920 #undef ADD_FIELD
2922 gfc_finish_type (select_struct[k]);
2925 n = 0;
2926 for (d = cp; d; d = d->right)
2927 d->n = n++;
2929 for (c = code->block; c; c = c->block)
2931 for (d = c->ext.block.case_list; d; d = d->next)
2933 label = gfc_build_label_decl (NULL_TREE);
2934 tmp = build_case_label ((d->low == NULL && d->high == NULL)
2935 ? NULL
2936 : build_int_cst (integer_type_node, d->n),
2937 NULL, label);
2938 gfc_add_expr_to_block (&body, tmp);
2941 tmp = gfc_trans_code (c->next);
2942 gfc_add_expr_to_block (&body, tmp);
2944 tmp = build1_v (GOTO_EXPR, end_label);
2945 gfc_add_expr_to_block (&body, tmp);
2948 /* Generate the structure describing the branches */
2949 for (d = cp; d; d = d->right)
2951 vec<constructor_elt, va_gc> *node = NULL;
2953 gfc_init_se (&se, NULL);
2955 if (d->low == NULL)
2957 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2958 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2960 else
2962 gfc_conv_expr_reference (&se, d->low);
2964 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2965 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2968 if (d->high == NULL)
2970 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2971 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2973 else
2975 gfc_init_se (&se, NULL);
2976 gfc_conv_expr_reference (&se, d->high);
2978 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
2979 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
2982 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
2983 build_int_cst (integer_type_node, d->n));
2985 tmp = build_constructor (select_struct[k], node);
2986 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
2989 type = build_array_type (select_struct[k],
2990 build_index_type (size_int (n-1)));
2992 init = build_constructor (type, inits);
2993 TREE_CONSTANT (init) = 1;
2994 TREE_STATIC (init) = 1;
2995 /* Create a static variable to hold the jump table. */
2996 tmp = gfc_create_var (type, "jumptable");
2997 TREE_CONSTANT (tmp) = 1;
2998 TREE_STATIC (tmp) = 1;
2999 TREE_READONLY (tmp) = 1;
3000 DECL_INITIAL (tmp) = init;
3001 init = tmp;
3003 /* Build the library call */
3004 init = gfc_build_addr_expr (pvoid_type_node, init);
3006 if (code->expr1->ts.kind == 1)
3007 fndecl = gfor_fndecl_select_string;
3008 else if (code->expr1->ts.kind == 4)
3009 fndecl = gfor_fndecl_select_string_char4;
3010 else
3011 gcc_unreachable ();
3013 tmp = build_call_expr_loc (input_location,
3014 fndecl, 4, init,
3015 build_int_cst (gfc_charlen_type_node, n),
3016 expr1se.expr, expr1se.string_length);
3017 case_num = gfc_create_var (integer_type_node, "case_num");
3018 gfc_add_modify (&block, case_num, tmp);
3020 gfc_add_block_to_block (&block, &expr1se.post);
3022 tmp = gfc_finish_block (&body);
3023 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
3024 case_num, tmp, NULL_TREE);
3025 gfc_add_expr_to_block (&block, tmp);
3027 tmp = build1_v (LABEL_EXPR, end_label);
3028 gfc_add_expr_to_block (&block, tmp);
3030 return gfc_finish_block (&block);
3034 /* Translate the three variants of the SELECT CASE construct.
3036 SELECT CASEs with INTEGER case expressions can be translated to an
3037 equivalent GENERIC switch statement, and for LOGICAL case
3038 expressions we build one or two if-else compares.
3040 SELECT CASEs with CHARACTER case expressions are a whole different
3041 story, because they don't exist in GENERIC. So we sort them and
3042 do a binary search at runtime.
3044 Fortran has no BREAK statement, and it does not allow jumps from
3045 one case block to another. That makes things a lot easier for
3046 the optimizers. */
3048 tree
3049 gfc_trans_select (gfc_code * code)
3051 stmtblock_t block;
3052 tree body;
3053 tree exit_label;
3055 gcc_assert (code && code->expr1);
3056 gfc_init_block (&block);
3058 /* Build the exit label and hang it in. */
3059 exit_label = gfc_build_label_decl (NULL_TREE);
3060 code->exit_label = exit_label;
3062 /* Empty SELECT constructs are legal. */
3063 if (code->block == NULL)
3064 body = build_empty_stmt (input_location);
3066 /* Select the correct translation function. */
3067 else
3068 switch (code->expr1->ts.type)
3070 case BT_LOGICAL:
3071 body = gfc_trans_logical_select (code);
3072 break;
3074 case BT_INTEGER:
3075 body = gfc_trans_integer_select (code);
3076 break;
3078 case BT_CHARACTER:
3079 body = gfc_trans_character_select (code);
3080 break;
3082 default:
3083 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3084 /* Not reached */
3087 /* Build everything together. */
3088 gfc_add_expr_to_block (&block, body);
3089 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3091 return gfc_finish_block (&block);
3094 tree
3095 gfc_trans_select_type (gfc_code * code)
3097 stmtblock_t block;
3098 tree body;
3099 tree exit_label;
3101 gcc_assert (code && code->expr1);
3102 gfc_init_block (&block);
3104 /* Build the exit label and hang it in. */
3105 exit_label = gfc_build_label_decl (NULL_TREE);
3106 code->exit_label = exit_label;
3108 /* Empty SELECT constructs are legal. */
3109 if (code->block == NULL)
3110 body = build_empty_stmt (input_location);
3111 else
3112 body = gfc_trans_select_type_cases (code);
3114 /* Build everything together. */
3115 gfc_add_expr_to_block (&block, body);
3117 if (TREE_USED (exit_label))
3118 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3120 return gfc_finish_block (&block);
3124 /* Traversal function to substitute a replacement symtree if the symbol
3125 in the expression is the same as that passed. f == 2 signals that
3126 that variable itself is not to be checked - only the references.
3127 This group of functions is used when the variable expression in a
3128 FORALL assignment has internal references. For example:
3129 FORALL (i = 1:4) p(p(i)) = i
3130 The only recourse here is to store a copy of 'p' for the index
3131 expression. */
3133 static gfc_symtree *new_symtree;
3134 static gfc_symtree *old_symtree;
3136 static bool
3137 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3139 if (expr->expr_type != EXPR_VARIABLE)
3140 return false;
3142 if (*f == 2)
3143 *f = 1;
3144 else if (expr->symtree->n.sym == sym)
3145 expr->symtree = new_symtree;
3147 return false;
3150 static void
3151 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3153 gfc_traverse_expr (e, sym, forall_replace, f);
3156 static bool
3157 forall_restore (gfc_expr *expr,
3158 gfc_symbol *sym ATTRIBUTE_UNUSED,
3159 int *f ATTRIBUTE_UNUSED)
3161 if (expr->expr_type != EXPR_VARIABLE)
3162 return false;
3164 if (expr->symtree == new_symtree)
3165 expr->symtree = old_symtree;
3167 return false;
3170 static void
3171 forall_restore_symtree (gfc_expr *e)
3173 gfc_traverse_expr (e, NULL, forall_restore, 0);
3176 static void
3177 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3179 gfc_se tse;
3180 gfc_se rse;
3181 gfc_expr *e;
3182 gfc_symbol *new_sym;
3183 gfc_symbol *old_sym;
3184 gfc_symtree *root;
3185 tree tmp;
3187 /* Build a copy of the lvalue. */
3188 old_symtree = c->expr1->symtree;
3189 old_sym = old_symtree->n.sym;
3190 e = gfc_lval_expr_from_sym (old_sym);
3191 if (old_sym->attr.dimension)
3193 gfc_init_se (&tse, NULL);
3194 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3195 gfc_add_block_to_block (pre, &tse.pre);
3196 gfc_add_block_to_block (post, &tse.post);
3197 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3199 if (e->ts.type != BT_CHARACTER)
3201 /* Use the variable offset for the temporary. */
3202 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3203 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3206 else
3208 gfc_init_se (&tse, NULL);
3209 gfc_init_se (&rse, NULL);
3210 gfc_conv_expr (&rse, e);
3211 if (e->ts.type == BT_CHARACTER)
3213 tse.string_length = rse.string_length;
3214 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3215 tse.string_length);
3216 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3217 rse.string_length);
3218 gfc_add_block_to_block (pre, &tse.pre);
3219 gfc_add_block_to_block (post, &tse.post);
3221 else
3223 tmp = gfc_typenode_for_spec (&e->ts);
3224 tse.expr = gfc_create_var (tmp, "temp");
3227 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3228 e->expr_type == EXPR_VARIABLE, false);
3229 gfc_add_expr_to_block (pre, tmp);
3231 gfc_free_expr (e);
3233 /* Create a new symbol to represent the lvalue. */
3234 new_sym = gfc_new_symbol (old_sym->name, NULL);
3235 new_sym->ts = old_sym->ts;
3236 new_sym->attr.referenced = 1;
3237 new_sym->attr.temporary = 1;
3238 new_sym->attr.dimension = old_sym->attr.dimension;
3239 new_sym->attr.flavor = old_sym->attr.flavor;
3241 /* Use the temporary as the backend_decl. */
3242 new_sym->backend_decl = tse.expr;
3244 /* Create a fake symtree for it. */
3245 root = NULL;
3246 new_symtree = gfc_new_symtree (&root, old_sym->name);
3247 new_symtree->n.sym = new_sym;
3248 gcc_assert (new_symtree == root);
3250 /* Go through the expression reference replacing the old_symtree
3251 with the new. */
3252 forall_replace_symtree (c->expr1, old_sym, 2);
3254 /* Now we have made this temporary, we might as well use it for
3255 the right hand side. */
3256 forall_replace_symtree (c->expr2, old_sym, 1);
3260 /* Handles dependencies in forall assignments. */
3261 static int
3262 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3264 gfc_ref *lref;
3265 gfc_ref *rref;
3266 int need_temp;
3267 gfc_symbol *lsym;
3269 lsym = c->expr1->symtree->n.sym;
3270 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3272 /* Now check for dependencies within the 'variable'
3273 expression itself. These are treated by making a complete
3274 copy of variable and changing all the references to it
3275 point to the copy instead. Note that the shallow copy of
3276 the variable will not suffice for derived types with
3277 pointer components. We therefore leave these to their
3278 own devices. */
3279 if (lsym->ts.type == BT_DERIVED
3280 && lsym->ts.u.derived->attr.pointer_comp)
3281 return need_temp;
3283 new_symtree = NULL;
3284 if (find_forall_index (c->expr1, lsym, 2))
3286 forall_make_variable_temp (c, pre, post);
3287 need_temp = 0;
3290 /* Substrings with dependencies are treated in the same
3291 way. */
3292 if (c->expr1->ts.type == BT_CHARACTER
3293 && c->expr1->ref
3294 && c->expr2->expr_type == EXPR_VARIABLE
3295 && lsym == c->expr2->symtree->n.sym)
3297 for (lref = c->expr1->ref; lref; lref = lref->next)
3298 if (lref->type == REF_SUBSTRING)
3299 break;
3300 for (rref = c->expr2->ref; rref; rref = rref->next)
3301 if (rref->type == REF_SUBSTRING)
3302 break;
3304 if (rref && lref
3305 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3307 forall_make_variable_temp (c, pre, post);
3308 need_temp = 0;
3311 return need_temp;
3315 static void
3316 cleanup_forall_symtrees (gfc_code *c)
3318 forall_restore_symtree (c->expr1);
3319 forall_restore_symtree (c->expr2);
3320 free (new_symtree->n.sym);
3321 free (new_symtree);
3325 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3326 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3327 indicates whether we should generate code to test the FORALLs mask
3328 array. OUTER is the loop header to be used for initializing mask
3329 indices.
3331 The generated loop format is:
3332 count = (end - start + step) / step
3333 loopvar = start
3334 while (1)
3336 if (count <=0 )
3337 goto end_of_loop
3338 <body>
3339 loopvar += step
3340 count --
3342 end_of_loop: */
3344 static tree
3345 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3346 int mask_flag, stmtblock_t *outer)
3348 int n, nvar;
3349 tree tmp;
3350 tree cond;
3351 stmtblock_t block;
3352 tree exit_label;
3353 tree count;
3354 tree var, start, end, step;
3355 iter_info *iter;
3357 /* Initialize the mask index outside the FORALL nest. */
3358 if (mask_flag && forall_tmp->mask)
3359 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3361 iter = forall_tmp->this_loop;
3362 nvar = forall_tmp->nvar;
3363 for (n = 0; n < nvar; n++)
3365 var = iter->var;
3366 start = iter->start;
3367 end = iter->end;
3368 step = iter->step;
3370 exit_label = gfc_build_label_decl (NULL_TREE);
3371 TREE_USED (exit_label) = 1;
3373 /* The loop counter. */
3374 count = gfc_create_var (TREE_TYPE (var), "count");
3376 /* The body of the loop. */
3377 gfc_init_block (&block);
3379 /* The exit condition. */
3380 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3381 count, build_int_cst (TREE_TYPE (count), 0));
3382 if (forall_tmp->do_concurrent)
3383 cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3384 build_int_cst (integer_type_node,
3385 annot_expr_ivdep_kind));
3387 tmp = build1_v (GOTO_EXPR, exit_label);
3388 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3389 cond, tmp, build_empty_stmt (input_location));
3390 gfc_add_expr_to_block (&block, tmp);
3392 /* The main loop body. */
3393 gfc_add_expr_to_block (&block, body);
3395 /* Increment the loop variable. */
3396 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3397 step);
3398 gfc_add_modify (&block, var, tmp);
3400 /* Advance to the next mask element. Only do this for the
3401 innermost loop. */
3402 if (n == 0 && mask_flag && forall_tmp->mask)
3404 tree maskindex = forall_tmp->maskindex;
3405 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3406 maskindex, gfc_index_one_node);
3407 gfc_add_modify (&block, maskindex, tmp);
3410 /* Decrement the loop counter. */
3411 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3412 build_int_cst (TREE_TYPE (var), 1));
3413 gfc_add_modify (&block, count, tmp);
3415 body = gfc_finish_block (&block);
3417 /* Loop var initialization. */
3418 gfc_init_block (&block);
3419 gfc_add_modify (&block, var, start);
3422 /* Initialize the loop counter. */
3423 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3424 start);
3425 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3426 tmp);
3427 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3428 tmp, step);
3429 gfc_add_modify (&block, count, tmp);
3431 /* The loop expression. */
3432 tmp = build1_v (LOOP_EXPR, body);
3433 gfc_add_expr_to_block (&block, tmp);
3435 /* The exit label. */
3436 tmp = build1_v (LABEL_EXPR, exit_label);
3437 gfc_add_expr_to_block (&block, tmp);
3439 body = gfc_finish_block (&block);
3440 iter = iter->next;
3442 return body;
3446 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3447 is nonzero, the body is controlled by all masks in the forall nest.
3448 Otherwise, the innermost loop is not controlled by it's mask. This
3449 is used for initializing that mask. */
3451 static tree
3452 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3453 int mask_flag)
3455 tree tmp;
3456 stmtblock_t header;
3457 forall_info *forall_tmp;
3458 tree mask, maskindex;
3460 gfc_start_block (&header);
3462 forall_tmp = nested_forall_info;
3463 while (forall_tmp != NULL)
3465 /* Generate body with masks' control. */
3466 if (mask_flag)
3468 mask = forall_tmp->mask;
3469 maskindex = forall_tmp->maskindex;
3471 /* If a mask was specified make the assignment conditional. */
3472 if (mask)
3474 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3475 body = build3_v (COND_EXPR, tmp, body,
3476 build_empty_stmt (input_location));
3479 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3480 forall_tmp = forall_tmp->prev_nest;
3481 mask_flag = 1;
3484 gfc_add_expr_to_block (&header, body);
3485 return gfc_finish_block (&header);
3489 /* Allocate data for holding a temporary array. Returns either a local
3490 temporary array or a pointer variable. */
3492 static tree
3493 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3494 tree elem_type)
3496 tree tmpvar;
3497 tree type;
3498 tree tmp;
3500 if (INTEGER_CST_P (size))
3501 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3502 size, gfc_index_one_node);
3503 else
3504 tmp = NULL_TREE;
3506 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3507 type = build_array_type (elem_type, type);
3508 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3510 tmpvar = gfc_create_var (type, "temp");
3511 *pdata = NULL_TREE;
3513 else
3515 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3516 *pdata = convert (pvoid_type_node, tmpvar);
3518 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3519 gfc_add_modify (pblock, tmpvar, tmp);
3521 return tmpvar;
3525 /* Generate codes to copy the temporary to the actual lhs. */
3527 static tree
3528 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3529 tree count1, tree wheremask, bool invert)
3531 gfc_ss *lss;
3532 gfc_se lse, rse;
3533 stmtblock_t block, body;
3534 gfc_loopinfo loop1;
3535 tree tmp;
3536 tree wheremaskexpr;
3538 /* Walk the lhs. */
3539 lss = gfc_walk_expr (expr);
3541 if (lss == gfc_ss_terminator)
3543 gfc_start_block (&block);
3545 gfc_init_se (&lse, NULL);
3547 /* Translate the expression. */
3548 gfc_conv_expr (&lse, expr);
3550 /* Form the expression for the temporary. */
3551 tmp = gfc_build_array_ref (tmp1, count1, NULL);
3553 /* Use the scalar assignment as is. */
3554 gfc_add_block_to_block (&block, &lse.pre);
3555 gfc_add_modify (&block, lse.expr, tmp);
3556 gfc_add_block_to_block (&block, &lse.post);
3558 /* Increment the count1. */
3559 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3560 count1, gfc_index_one_node);
3561 gfc_add_modify (&block, count1, tmp);
3563 tmp = gfc_finish_block (&block);
3565 else
3567 gfc_start_block (&block);
3569 gfc_init_loopinfo (&loop1);
3570 gfc_init_se (&rse, NULL);
3571 gfc_init_se (&lse, NULL);
3573 /* Associate the lss with the loop. */
3574 gfc_add_ss_to_loop (&loop1, lss);
3576 /* Calculate the bounds of the scalarization. */
3577 gfc_conv_ss_startstride (&loop1);
3578 /* Setup the scalarizing loops. */
3579 gfc_conv_loop_setup (&loop1, &expr->where);
3581 gfc_mark_ss_chain_used (lss, 1);
3583 /* Start the scalarized loop body. */
3584 gfc_start_scalarized_body (&loop1, &body);
3586 /* Setup the gfc_se structures. */
3587 gfc_copy_loopinfo_to_se (&lse, &loop1);
3588 lse.ss = lss;
3590 /* Form the expression of the temporary. */
3591 if (lss != gfc_ss_terminator)
3592 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3593 /* Translate expr. */
3594 gfc_conv_expr (&lse, expr);
3596 /* Use the scalar assignment. */
3597 rse.string_length = lse.string_length;
3598 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, true);
3600 /* Form the mask expression according to the mask tree list. */
3601 if (wheremask)
3603 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3604 if (invert)
3605 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3606 TREE_TYPE (wheremaskexpr),
3607 wheremaskexpr);
3608 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3609 wheremaskexpr, tmp,
3610 build_empty_stmt (input_location));
3613 gfc_add_expr_to_block (&body, tmp);
3615 /* Increment count1. */
3616 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3617 count1, gfc_index_one_node);
3618 gfc_add_modify (&body, count1, tmp);
3620 /* Increment count3. */
3621 if (count3)
3623 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3624 gfc_array_index_type, count3,
3625 gfc_index_one_node);
3626 gfc_add_modify (&body, count3, tmp);
3629 /* Generate the copying loops. */
3630 gfc_trans_scalarizing_loops (&loop1, &body);
3631 gfc_add_block_to_block (&block, &loop1.pre);
3632 gfc_add_block_to_block (&block, &loop1.post);
3633 gfc_cleanup_loop (&loop1);
3635 tmp = gfc_finish_block (&block);
3637 return tmp;
3641 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3642 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3643 and should not be freed. WHEREMASK is the conditional execution mask
3644 whose sense may be inverted by INVERT. */
3646 static tree
3647 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3648 tree count1, gfc_ss *lss, gfc_ss *rss,
3649 tree wheremask, bool invert)
3651 stmtblock_t block, body1;
3652 gfc_loopinfo loop;
3653 gfc_se lse;
3654 gfc_se rse;
3655 tree tmp;
3656 tree wheremaskexpr;
3658 gfc_start_block (&block);
3660 gfc_init_se (&rse, NULL);
3661 gfc_init_se (&lse, NULL);
3663 if (lss == gfc_ss_terminator)
3665 gfc_init_block (&body1);
3666 gfc_conv_expr (&rse, expr2);
3667 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3669 else
3671 /* Initialize the loop. */
3672 gfc_init_loopinfo (&loop);
3674 /* We may need LSS to determine the shape of the expression. */
3675 gfc_add_ss_to_loop (&loop, lss);
3676 gfc_add_ss_to_loop (&loop, rss);
3678 gfc_conv_ss_startstride (&loop);
3679 gfc_conv_loop_setup (&loop, &expr2->where);
3681 gfc_mark_ss_chain_used (rss, 1);
3682 /* Start the loop body. */
3683 gfc_start_scalarized_body (&loop, &body1);
3685 /* Translate the expression. */
3686 gfc_copy_loopinfo_to_se (&rse, &loop);
3687 rse.ss = rss;
3688 gfc_conv_expr (&rse, expr2);
3690 /* Form the expression of the temporary. */
3691 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3694 /* Use the scalar assignment. */
3695 lse.string_length = rse.string_length;
3696 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3697 expr2->expr_type == EXPR_VARIABLE, false);
3699 /* Form the mask expression according to the mask tree list. */
3700 if (wheremask)
3702 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3703 if (invert)
3704 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3705 TREE_TYPE (wheremaskexpr),
3706 wheremaskexpr);
3707 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3708 wheremaskexpr, tmp,
3709 build_empty_stmt (input_location));
3712 gfc_add_expr_to_block (&body1, tmp);
3714 if (lss == gfc_ss_terminator)
3716 gfc_add_block_to_block (&block, &body1);
3718 /* Increment count1. */
3719 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3720 count1, gfc_index_one_node);
3721 gfc_add_modify (&block, count1, tmp);
3723 else
3725 /* Increment count1. */
3726 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3727 count1, gfc_index_one_node);
3728 gfc_add_modify (&body1, count1, tmp);
3730 /* Increment count3. */
3731 if (count3)
3733 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3734 gfc_array_index_type,
3735 count3, gfc_index_one_node);
3736 gfc_add_modify (&body1, count3, tmp);
3739 /* Generate the copying loops. */
3740 gfc_trans_scalarizing_loops (&loop, &body1);
3742 gfc_add_block_to_block (&block, &loop.pre);
3743 gfc_add_block_to_block (&block, &loop.post);
3745 gfc_cleanup_loop (&loop);
3746 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3747 as tree nodes in SS may not be valid in different scope. */
3750 tmp = gfc_finish_block (&block);
3751 return tmp;
3755 /* Calculate the size of temporary needed in the assignment inside forall.
3756 LSS and RSS are filled in this function. */
3758 static tree
3759 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3760 stmtblock_t * pblock,
3761 gfc_ss **lss, gfc_ss **rss)
3763 gfc_loopinfo loop;
3764 tree size;
3765 int i;
3766 int save_flag;
3767 tree tmp;
3769 *lss = gfc_walk_expr (expr1);
3770 *rss = NULL;
3772 size = gfc_index_one_node;
3773 if (*lss != gfc_ss_terminator)
3775 gfc_init_loopinfo (&loop);
3777 /* Walk the RHS of the expression. */
3778 *rss = gfc_walk_expr (expr2);
3779 if (*rss == gfc_ss_terminator)
3780 /* The rhs is scalar. Add a ss for the expression. */
3781 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3783 /* Associate the SS with the loop. */
3784 gfc_add_ss_to_loop (&loop, *lss);
3785 /* We don't actually need to add the rhs at this point, but it might
3786 make guessing the loop bounds a bit easier. */
3787 gfc_add_ss_to_loop (&loop, *rss);
3789 /* We only want the shape of the expression, not rest of the junk
3790 generated by the scalarizer. */
3791 loop.array_parameter = 1;
3793 /* Calculate the bounds of the scalarization. */
3794 save_flag = gfc_option.rtcheck;
3795 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3796 gfc_conv_ss_startstride (&loop);
3797 gfc_option.rtcheck = save_flag;
3798 gfc_conv_loop_setup (&loop, &expr2->where);
3800 /* Figure out how many elements we need. */
3801 for (i = 0; i < loop.dimen; i++)
3803 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3804 gfc_array_index_type,
3805 gfc_index_one_node, loop.from[i]);
3806 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3807 gfc_array_index_type, tmp, loop.to[i]);
3808 size = fold_build2_loc (input_location, MULT_EXPR,
3809 gfc_array_index_type, size, tmp);
3811 gfc_add_block_to_block (pblock, &loop.pre);
3812 size = gfc_evaluate_now (size, pblock);
3813 gfc_add_block_to_block (pblock, &loop.post);
3815 /* TODO: write a function that cleans up a loopinfo without freeing
3816 the SS chains. Currently a NOP. */
3819 return size;
3823 /* Calculate the overall iterator number of the nested forall construct.
3824 This routine actually calculates the number of times the body of the
3825 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3826 that by the expression INNER_SIZE. The BLOCK argument specifies the
3827 block in which to calculate the result, and the optional INNER_SIZE_BODY
3828 argument contains any statements that need to executed (inside the loop)
3829 to initialize or calculate INNER_SIZE. */
3831 static tree
3832 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3833 stmtblock_t *inner_size_body, stmtblock_t *block)
3835 forall_info *forall_tmp = nested_forall_info;
3836 tree tmp, number;
3837 stmtblock_t body;
3839 /* We can eliminate the innermost unconditional loops with constant
3840 array bounds. */
3841 if (INTEGER_CST_P (inner_size))
3843 while (forall_tmp
3844 && !forall_tmp->mask
3845 && INTEGER_CST_P (forall_tmp->size))
3847 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3848 gfc_array_index_type,
3849 inner_size, forall_tmp->size);
3850 forall_tmp = forall_tmp->prev_nest;
3853 /* If there are no loops left, we have our constant result. */
3854 if (!forall_tmp)
3855 return inner_size;
3858 /* Otherwise, create a temporary variable to compute the result. */
3859 number = gfc_create_var (gfc_array_index_type, "num");
3860 gfc_add_modify (block, number, gfc_index_zero_node);
3862 gfc_start_block (&body);
3863 if (inner_size_body)
3864 gfc_add_block_to_block (&body, inner_size_body);
3865 if (forall_tmp)
3866 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3867 gfc_array_index_type, number, inner_size);
3868 else
3869 tmp = inner_size;
3870 gfc_add_modify (&body, number, tmp);
3871 tmp = gfc_finish_block (&body);
3873 /* Generate loops. */
3874 if (forall_tmp != NULL)
3875 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3877 gfc_add_expr_to_block (block, tmp);
3879 return number;
3883 /* Allocate temporary for forall construct. SIZE is the size of temporary
3884 needed. PTEMP1 is returned for space free. */
3886 static tree
3887 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3888 tree * ptemp1)
3890 tree bytesize;
3891 tree unit;
3892 tree tmp;
3894 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3895 if (!integer_onep (unit))
3896 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3897 gfc_array_index_type, size, unit);
3898 else
3899 bytesize = size;
3901 *ptemp1 = NULL;
3902 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3904 if (*ptemp1)
3905 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3906 return tmp;
3910 /* Allocate temporary for forall construct according to the information in
3911 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3912 assignment inside forall. PTEMP1 is returned for space free. */
3914 static tree
3915 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3916 tree inner_size, stmtblock_t * inner_size_body,
3917 stmtblock_t * block, tree * ptemp1)
3919 tree size;
3921 /* Calculate the total size of temporary needed in forall construct. */
3922 size = compute_overall_iter_number (nested_forall_info, inner_size,
3923 inner_size_body, block);
3925 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3929 /* Handle assignments inside forall which need temporary.
3931 forall (i=start:end:stride; maskexpr)
3932 e<i> = f<i>
3933 end forall
3934 (where e,f<i> are arbitrary expressions possibly involving i
3935 and there is a dependency between e<i> and f<i>)
3936 Translates to:
3937 masktmp(:) = maskexpr(:)
3939 maskindex = 0;
3940 count1 = 0;
3941 num = 0;
3942 for (i = start; i <= end; i += stride)
3943 num += SIZE (f<i>)
3944 count1 = 0;
3945 ALLOCATE (tmp(num))
3946 for (i = start; i <= end; i += stride)
3948 if (masktmp[maskindex++])
3949 tmp[count1++] = f<i>
3951 maskindex = 0;
3952 count1 = 0;
3953 for (i = start; i <= end; i += stride)
3955 if (masktmp[maskindex++])
3956 e<i> = tmp[count1++]
3958 DEALLOCATE (tmp)
3960 static void
3961 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3962 tree wheremask, bool invert,
3963 forall_info * nested_forall_info,
3964 stmtblock_t * block)
3966 tree type;
3967 tree inner_size;
3968 gfc_ss *lss, *rss;
3969 tree count, count1;
3970 tree tmp, tmp1;
3971 tree ptemp1;
3972 stmtblock_t inner_size_body;
3974 /* Create vars. count1 is the current iterator number of the nested
3975 forall. */
3976 count1 = gfc_create_var (gfc_array_index_type, "count1");
3978 /* Count is the wheremask index. */
3979 if (wheremask)
3981 count = gfc_create_var (gfc_array_index_type, "count");
3982 gfc_add_modify (block, count, gfc_index_zero_node);
3984 else
3985 count = NULL;
3987 /* Initialize count1. */
3988 gfc_add_modify (block, count1, gfc_index_zero_node);
3990 /* Calculate the size of temporary needed in the assignment. Return loop, lss
3991 and rss which are used in function generate_loop_for_rhs_to_temp(). */
3992 gfc_init_block (&inner_size_body);
3993 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
3994 &lss, &rss);
3996 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3997 if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->length)
3999 if (!expr1->ts.u.cl->backend_decl)
4001 gfc_se tse;
4002 gfc_init_se (&tse, NULL);
4003 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4004 expr1->ts.u.cl->backend_decl = tse.expr;
4006 type = gfc_get_character_type_len (gfc_default_character_kind,
4007 expr1->ts.u.cl->backend_decl);
4009 else
4010 type = gfc_typenode_for_spec (&expr1->ts);
4012 /* Allocate temporary for nested forall construct according to the
4013 information in nested_forall_info and inner_size. */
4014 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4015 &inner_size_body, block, &ptemp1);
4017 /* Generate codes to copy rhs to the temporary . */
4018 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4019 wheremask, invert);
4021 /* Generate body and loops according to the information in
4022 nested_forall_info. */
4023 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4024 gfc_add_expr_to_block (block, tmp);
4026 /* Reset count1. */
4027 gfc_add_modify (block, count1, gfc_index_zero_node);
4029 /* Reset count. */
4030 if (wheremask)
4031 gfc_add_modify (block, count, gfc_index_zero_node);
4033 /* Generate codes to copy the temporary to lhs. */
4034 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4035 wheremask, invert);
4037 /* Generate body and loops according to the information in
4038 nested_forall_info. */
4039 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4040 gfc_add_expr_to_block (block, tmp);
4042 if (ptemp1)
4044 /* Free the temporary. */
4045 tmp = gfc_call_free (ptemp1);
4046 gfc_add_expr_to_block (block, tmp);
4051 /* Translate pointer assignment inside FORALL which need temporary. */
4053 static void
4054 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4055 forall_info * nested_forall_info,
4056 stmtblock_t * block)
4058 tree type;
4059 tree inner_size;
4060 gfc_ss *lss, *rss;
4061 gfc_se lse;
4062 gfc_se rse;
4063 gfc_array_info *info;
4064 gfc_loopinfo loop;
4065 tree desc;
4066 tree parm;
4067 tree parmtype;
4068 stmtblock_t body;
4069 tree count;
4070 tree tmp, tmp1, ptemp1;
4072 count = gfc_create_var (gfc_array_index_type, "count");
4073 gfc_add_modify (block, count, gfc_index_zero_node);
4075 inner_size = gfc_index_one_node;
4076 lss = gfc_walk_expr (expr1);
4077 rss = gfc_walk_expr (expr2);
4078 if (lss == gfc_ss_terminator)
4080 type = gfc_typenode_for_spec (&expr1->ts);
4081 type = build_pointer_type (type);
4083 /* Allocate temporary for nested forall construct according to the
4084 information in nested_forall_info and inner_size. */
4085 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4086 inner_size, NULL, block, &ptemp1);
4087 gfc_start_block (&body);
4088 gfc_init_se (&lse, NULL);
4089 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4090 gfc_init_se (&rse, NULL);
4091 rse.want_pointer = 1;
4092 gfc_conv_expr (&rse, expr2);
4093 gfc_add_block_to_block (&body, &rse.pre);
4094 gfc_add_modify (&body, lse.expr,
4095 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4096 gfc_add_block_to_block (&body, &rse.post);
4098 /* Increment count. */
4099 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4100 count, gfc_index_one_node);
4101 gfc_add_modify (&body, count, tmp);
4103 tmp = gfc_finish_block (&body);
4105 /* Generate body and loops according to the information in
4106 nested_forall_info. */
4107 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4108 gfc_add_expr_to_block (block, tmp);
4110 /* Reset count. */
4111 gfc_add_modify (block, count, gfc_index_zero_node);
4113 gfc_start_block (&body);
4114 gfc_init_se (&lse, NULL);
4115 gfc_init_se (&rse, NULL);
4116 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4117 lse.want_pointer = 1;
4118 gfc_conv_expr (&lse, expr1);
4119 gfc_add_block_to_block (&body, &lse.pre);
4120 gfc_add_modify (&body, lse.expr, rse.expr);
4121 gfc_add_block_to_block (&body, &lse.post);
4122 /* Increment count. */
4123 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4124 count, gfc_index_one_node);
4125 gfc_add_modify (&body, count, tmp);
4126 tmp = gfc_finish_block (&body);
4128 /* Generate body and loops according to the information in
4129 nested_forall_info. */
4130 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4131 gfc_add_expr_to_block (block, tmp);
4133 else
4135 gfc_init_loopinfo (&loop);
4137 /* Associate the SS with the loop. */
4138 gfc_add_ss_to_loop (&loop, rss);
4140 /* Setup the scalarizing loops and bounds. */
4141 gfc_conv_ss_startstride (&loop);
4143 gfc_conv_loop_setup (&loop, &expr2->where);
4145 info = &rss->info->data.array;
4146 desc = info->descriptor;
4148 /* Make a new descriptor. */
4149 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4150 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4151 loop.from, loop.to, 1,
4152 GFC_ARRAY_UNKNOWN, true);
4154 /* Allocate temporary for nested forall construct. */
4155 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4156 inner_size, NULL, block, &ptemp1);
4157 gfc_start_block (&body);
4158 gfc_init_se (&lse, NULL);
4159 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4160 lse.direct_byref = 1;
4161 gfc_conv_expr_descriptor (&lse, expr2);
4163 gfc_add_block_to_block (&body, &lse.pre);
4164 gfc_add_block_to_block (&body, &lse.post);
4166 /* Increment count. */
4167 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4168 count, gfc_index_one_node);
4169 gfc_add_modify (&body, count, tmp);
4171 tmp = gfc_finish_block (&body);
4173 /* Generate body and loops according to the information in
4174 nested_forall_info. */
4175 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4176 gfc_add_expr_to_block (block, tmp);
4178 /* Reset count. */
4179 gfc_add_modify (block, count, gfc_index_zero_node);
4181 parm = gfc_build_array_ref (tmp1, count, NULL);
4182 gfc_init_se (&lse, NULL);
4183 gfc_conv_expr_descriptor (&lse, expr1);
4184 gfc_add_modify (&lse.pre, lse.expr, parm);
4185 gfc_start_block (&body);
4186 gfc_add_block_to_block (&body, &lse.pre);
4187 gfc_add_block_to_block (&body, &lse.post);
4189 /* Increment count. */
4190 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4191 count, gfc_index_one_node);
4192 gfc_add_modify (&body, count, tmp);
4194 tmp = gfc_finish_block (&body);
4196 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4197 gfc_add_expr_to_block (block, tmp);
4199 /* Free the temporary. */
4200 if (ptemp1)
4202 tmp = gfc_call_free (ptemp1);
4203 gfc_add_expr_to_block (block, tmp);
4208 /* FORALL and WHERE statements are really nasty, especially when you nest
4209 them. All the rhs of a forall assignment must be evaluated before the
4210 actual assignments are performed. Presumably this also applies to all the
4211 assignments in an inner where statement. */
4213 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4214 linear array, relying on the fact that we process in the same order in all
4215 loops.
4217 forall (i=start:end:stride; maskexpr)
4218 e<i> = f<i>
4219 g<i> = h<i>
4220 end forall
4221 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4222 Translates to:
4223 count = ((end + 1 - start) / stride)
4224 masktmp(:) = maskexpr(:)
4226 maskindex = 0;
4227 for (i = start; i <= end; i += stride)
4229 if (masktmp[maskindex++])
4230 e<i> = f<i>
4232 maskindex = 0;
4233 for (i = start; i <= end; i += stride)
4235 if (masktmp[maskindex++])
4236 g<i> = h<i>
4239 Note that this code only works when there are no dependencies.
4240 Forall loop with array assignments and data dependencies are a real pain,
4241 because the size of the temporary cannot always be determined before the
4242 loop is executed. This problem is compounded by the presence of nested
4243 FORALL constructs.
4246 static tree
4247 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4249 stmtblock_t pre;
4250 stmtblock_t post;
4251 stmtblock_t block;
4252 stmtblock_t body;
4253 tree *var;
4254 tree *start;
4255 tree *end;
4256 tree *step;
4257 gfc_expr **varexpr;
4258 tree tmp;
4259 tree assign;
4260 tree size;
4261 tree maskindex;
4262 tree mask;
4263 tree pmask;
4264 tree cycle_label = NULL_TREE;
4265 int n;
4266 int nvar;
4267 int need_temp;
4268 gfc_forall_iterator *fa;
4269 gfc_se se;
4270 gfc_code *c;
4271 gfc_saved_var *saved_vars;
4272 iter_info *this_forall;
4273 forall_info *info;
4274 bool need_mask;
4276 /* Do nothing if the mask is false. */
4277 if (code->expr1
4278 && code->expr1->expr_type == EXPR_CONSTANT
4279 && !code->expr1->value.logical)
4280 return build_empty_stmt (input_location);
4282 n = 0;
4283 /* Count the FORALL index number. */
4284 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4285 n++;
4286 nvar = n;
4288 /* Allocate the space for var, start, end, step, varexpr. */
4289 var = XCNEWVEC (tree, nvar);
4290 start = XCNEWVEC (tree, nvar);
4291 end = XCNEWVEC (tree, nvar);
4292 step = XCNEWVEC (tree, nvar);
4293 varexpr = XCNEWVEC (gfc_expr *, nvar);
4294 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4296 /* Allocate the space for info. */
4297 info = XCNEW (forall_info);
4299 gfc_start_block (&pre);
4300 gfc_init_block (&post);
4301 gfc_init_block (&block);
4303 n = 0;
4304 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4306 gfc_symbol *sym = fa->var->symtree->n.sym;
4308 /* Allocate space for this_forall. */
4309 this_forall = XCNEW (iter_info);
4311 /* Create a temporary variable for the FORALL index. */
4312 tmp = gfc_typenode_for_spec (&sym->ts);
4313 var[n] = gfc_create_var (tmp, sym->name);
4314 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4316 /* Record it in this_forall. */
4317 this_forall->var = var[n];
4319 /* Replace the index symbol's backend_decl with the temporary decl. */
4320 sym->backend_decl = var[n];
4322 /* Work out the start, end and stride for the loop. */
4323 gfc_init_se (&se, NULL);
4324 gfc_conv_expr_val (&se, fa->start);
4325 /* Record it in this_forall. */
4326 this_forall->start = se.expr;
4327 gfc_add_block_to_block (&block, &se.pre);
4328 start[n] = se.expr;
4330 gfc_init_se (&se, NULL);
4331 gfc_conv_expr_val (&se, fa->end);
4332 /* Record it in this_forall. */
4333 this_forall->end = se.expr;
4334 gfc_make_safe_expr (&se);
4335 gfc_add_block_to_block (&block, &se.pre);
4336 end[n] = se.expr;
4338 gfc_init_se (&se, NULL);
4339 gfc_conv_expr_val (&se, fa->stride);
4340 /* Record it in this_forall. */
4341 this_forall->step = se.expr;
4342 gfc_make_safe_expr (&se);
4343 gfc_add_block_to_block (&block, &se.pre);
4344 step[n] = se.expr;
4346 /* Set the NEXT field of this_forall to NULL. */
4347 this_forall->next = NULL;
4348 /* Link this_forall to the info construct. */
4349 if (info->this_loop)
4351 iter_info *iter_tmp = info->this_loop;
4352 while (iter_tmp->next != NULL)
4353 iter_tmp = iter_tmp->next;
4354 iter_tmp->next = this_forall;
4356 else
4357 info->this_loop = this_forall;
4359 n++;
4361 nvar = n;
4363 /* Calculate the size needed for the current forall level. */
4364 size = gfc_index_one_node;
4365 for (n = 0; n < nvar; n++)
4367 /* size = (end + step - start) / step. */
4368 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4369 step[n], start[n]);
4370 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4371 end[n], tmp);
4372 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4373 tmp, step[n]);
4374 tmp = convert (gfc_array_index_type, tmp);
4376 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4377 size, tmp);
4380 /* Record the nvar and size of current forall level. */
4381 info->nvar = nvar;
4382 info->size = size;
4384 if (code->expr1)
4386 /* If the mask is .true., consider the FORALL unconditional. */
4387 if (code->expr1->expr_type == EXPR_CONSTANT
4388 && code->expr1->value.logical)
4389 need_mask = false;
4390 else
4391 need_mask = true;
4393 else
4394 need_mask = false;
4396 /* First we need to allocate the mask. */
4397 if (need_mask)
4399 /* As the mask array can be very big, prefer compact boolean types. */
4400 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4401 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4402 size, NULL, &block, &pmask);
4403 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4405 /* Record them in the info structure. */
4406 info->maskindex = maskindex;
4407 info->mask = mask;
4409 else
4411 /* No mask was specified. */
4412 maskindex = NULL_TREE;
4413 mask = pmask = NULL_TREE;
4416 /* Link the current forall level to nested_forall_info. */
4417 info->prev_nest = nested_forall_info;
4418 nested_forall_info = info;
4420 /* Copy the mask into a temporary variable if required.
4421 For now we assume a mask temporary is needed. */
4422 if (need_mask)
4424 /* As the mask array can be very big, prefer compact boolean types. */
4425 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4427 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4429 /* Start of mask assignment loop body. */
4430 gfc_start_block (&body);
4432 /* Evaluate the mask expression. */
4433 gfc_init_se (&se, NULL);
4434 gfc_conv_expr_val (&se, code->expr1);
4435 gfc_add_block_to_block (&body, &se.pre);
4437 /* Store the mask. */
4438 se.expr = convert (mask_type, se.expr);
4440 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4441 gfc_add_modify (&body, tmp, se.expr);
4443 /* Advance to the next mask element. */
4444 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4445 maskindex, gfc_index_one_node);
4446 gfc_add_modify (&body, maskindex, tmp);
4448 /* Generate the loops. */
4449 tmp = gfc_finish_block (&body);
4450 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4451 gfc_add_expr_to_block (&block, tmp);
4454 if (code->op == EXEC_DO_CONCURRENT)
4456 gfc_init_block (&body);
4457 cycle_label = gfc_build_label_decl (NULL_TREE);
4458 code->cycle_label = cycle_label;
4459 tmp = gfc_trans_code (code->block->next);
4460 gfc_add_expr_to_block (&body, tmp);
4462 if (TREE_USED (cycle_label))
4464 tmp = build1_v (LABEL_EXPR, cycle_label);
4465 gfc_add_expr_to_block (&body, tmp);
4468 tmp = gfc_finish_block (&body);
4469 nested_forall_info->do_concurrent = true;
4470 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4471 gfc_add_expr_to_block (&block, tmp);
4472 goto done;
4475 c = code->block->next;
4477 /* TODO: loop merging in FORALL statements. */
4478 /* Now that we've got a copy of the mask, generate the assignment loops. */
4479 while (c)
4481 switch (c->op)
4483 case EXEC_ASSIGN:
4484 /* A scalar or array assignment. DO the simple check for
4485 lhs to rhs dependencies. These make a temporary for the
4486 rhs and form a second forall block to copy to variable. */
4487 need_temp = check_forall_dependencies(c, &pre, &post);
4489 /* Temporaries due to array assignment data dependencies introduce
4490 no end of problems. */
4491 if (need_temp)
4492 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4493 nested_forall_info, &block);
4494 else
4496 /* Use the normal assignment copying routines. */
4497 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4499 /* Generate body and loops. */
4500 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4501 assign, 1);
4502 gfc_add_expr_to_block (&block, tmp);
4505 /* Cleanup any temporary symtrees that have been made to deal
4506 with dependencies. */
4507 if (new_symtree)
4508 cleanup_forall_symtrees (c);
4510 break;
4512 case EXEC_WHERE:
4513 /* Translate WHERE or WHERE construct nested in FORALL. */
4514 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4515 break;
4517 /* Pointer assignment inside FORALL. */
4518 case EXEC_POINTER_ASSIGN:
4519 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4520 if (need_temp)
4521 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4522 nested_forall_info, &block);
4523 else
4525 /* Use the normal assignment copying routines. */
4526 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4528 /* Generate body and loops. */
4529 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4530 assign, 1);
4531 gfc_add_expr_to_block (&block, tmp);
4533 break;
4535 case EXEC_FORALL:
4536 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4537 gfc_add_expr_to_block (&block, tmp);
4538 break;
4540 /* Explicit subroutine calls are prevented by the frontend but interface
4541 assignments can legitimately produce them. */
4542 case EXEC_ASSIGN_CALL:
4543 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4544 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4545 gfc_add_expr_to_block (&block, tmp);
4546 break;
4548 default:
4549 gcc_unreachable ();
4552 c = c->next;
4555 done:
4556 /* Restore the original index variables. */
4557 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4558 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4560 /* Free the space for var, start, end, step, varexpr. */
4561 free (var);
4562 free (start);
4563 free (end);
4564 free (step);
4565 free (varexpr);
4566 free (saved_vars);
4568 for (this_forall = info->this_loop; this_forall;)
4570 iter_info *next = this_forall->next;
4571 free (this_forall);
4572 this_forall = next;
4575 /* Free the space for this forall_info. */
4576 free (info);
4578 if (pmask)
4580 /* Free the temporary for the mask. */
4581 tmp = gfc_call_free (pmask);
4582 gfc_add_expr_to_block (&block, tmp);
4584 if (maskindex)
4585 pushdecl (maskindex);
4587 gfc_add_block_to_block (&pre, &block);
4588 gfc_add_block_to_block (&pre, &post);
4590 return gfc_finish_block (&pre);
4594 /* Translate the FORALL statement or construct. */
4596 tree gfc_trans_forall (gfc_code * code)
4598 return gfc_trans_forall_1 (code, NULL);
4602 /* Translate the DO CONCURRENT construct. */
4604 tree gfc_trans_do_concurrent (gfc_code * code)
4606 return gfc_trans_forall_1 (code, NULL);
4610 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4611 If the WHERE construct is nested in FORALL, compute the overall temporary
4612 needed by the WHERE mask expression multiplied by the iterator number of
4613 the nested forall.
4614 ME is the WHERE mask expression.
4615 MASK is the current execution mask upon input, whose sense may or may
4616 not be inverted as specified by the INVERT argument.
4617 CMASK is the updated execution mask on output, or NULL if not required.
4618 PMASK is the pending execution mask on output, or NULL if not required.
4619 BLOCK is the block in which to place the condition evaluation loops. */
4621 static void
4622 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4623 tree mask, bool invert, tree cmask, tree pmask,
4624 tree mask_type, stmtblock_t * block)
4626 tree tmp, tmp1;
4627 gfc_ss *lss, *rss;
4628 gfc_loopinfo loop;
4629 stmtblock_t body, body1;
4630 tree count, cond, mtmp;
4631 gfc_se lse, rse;
4633 gfc_init_loopinfo (&loop);
4635 lss = gfc_walk_expr (me);
4636 rss = gfc_walk_expr (me);
4638 /* Variable to index the temporary. */
4639 count = gfc_create_var (gfc_array_index_type, "count");
4640 /* Initialize count. */
4641 gfc_add_modify (block, count, gfc_index_zero_node);
4643 gfc_start_block (&body);
4645 gfc_init_se (&rse, NULL);
4646 gfc_init_se (&lse, NULL);
4648 if (lss == gfc_ss_terminator)
4650 gfc_init_block (&body1);
4652 else
4654 /* Initialize the loop. */
4655 gfc_init_loopinfo (&loop);
4657 /* We may need LSS to determine the shape of the expression. */
4658 gfc_add_ss_to_loop (&loop, lss);
4659 gfc_add_ss_to_loop (&loop, rss);
4661 gfc_conv_ss_startstride (&loop);
4662 gfc_conv_loop_setup (&loop, &me->where);
4664 gfc_mark_ss_chain_used (rss, 1);
4665 /* Start the loop body. */
4666 gfc_start_scalarized_body (&loop, &body1);
4668 /* Translate the expression. */
4669 gfc_copy_loopinfo_to_se (&rse, &loop);
4670 rse.ss = rss;
4671 gfc_conv_expr (&rse, me);
4674 /* Variable to evaluate mask condition. */
4675 cond = gfc_create_var (mask_type, "cond");
4676 if (mask && (cmask || pmask))
4677 mtmp = gfc_create_var (mask_type, "mask");
4678 else mtmp = NULL_TREE;
4680 gfc_add_block_to_block (&body1, &lse.pre);
4681 gfc_add_block_to_block (&body1, &rse.pre);
4683 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4685 if (mask && (cmask || pmask))
4687 tmp = gfc_build_array_ref (mask, count, NULL);
4688 if (invert)
4689 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4690 gfc_add_modify (&body1, mtmp, tmp);
4693 if (cmask)
4695 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4696 tmp = cond;
4697 if (mask)
4698 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4699 mtmp, tmp);
4700 gfc_add_modify (&body1, tmp1, tmp);
4703 if (pmask)
4705 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4706 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4707 if (mask)
4708 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4709 tmp);
4710 gfc_add_modify (&body1, tmp1, tmp);
4713 gfc_add_block_to_block (&body1, &lse.post);
4714 gfc_add_block_to_block (&body1, &rse.post);
4716 if (lss == gfc_ss_terminator)
4718 gfc_add_block_to_block (&body, &body1);
4720 else
4722 /* Increment count. */
4723 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4724 count, gfc_index_one_node);
4725 gfc_add_modify (&body1, count, tmp1);
4727 /* Generate the copying loops. */
4728 gfc_trans_scalarizing_loops (&loop, &body1);
4730 gfc_add_block_to_block (&body, &loop.pre);
4731 gfc_add_block_to_block (&body, &loop.post);
4733 gfc_cleanup_loop (&loop);
4734 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4735 as tree nodes in SS may not be valid in different scope. */
4738 tmp1 = gfc_finish_block (&body);
4739 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4740 if (nested_forall_info != NULL)
4741 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4743 gfc_add_expr_to_block (block, tmp1);
4747 /* Translate an assignment statement in a WHERE statement or construct
4748 statement. The MASK expression is used to control which elements
4749 of EXPR1 shall be assigned. The sense of MASK is specified by
4750 INVERT. */
4752 static tree
4753 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4754 tree mask, bool invert,
4755 tree count1, tree count2,
4756 gfc_code *cnext)
4758 gfc_se lse;
4759 gfc_se rse;
4760 gfc_ss *lss;
4761 gfc_ss *lss_section;
4762 gfc_ss *rss;
4764 gfc_loopinfo loop;
4765 tree tmp;
4766 stmtblock_t block;
4767 stmtblock_t body;
4768 tree index, maskexpr;
4770 /* A defined assignment. */
4771 if (cnext && cnext->resolved_sym)
4772 return gfc_trans_call (cnext, true, mask, count1, invert);
4774 #if 0
4775 /* TODO: handle this special case.
4776 Special case a single function returning an array. */
4777 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4779 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4780 if (tmp)
4781 return tmp;
4783 #endif
4785 /* Assignment of the form lhs = rhs. */
4786 gfc_start_block (&block);
4788 gfc_init_se (&lse, NULL);
4789 gfc_init_se (&rse, NULL);
4791 /* Walk the lhs. */
4792 lss = gfc_walk_expr (expr1);
4793 rss = NULL;
4795 /* In each where-assign-stmt, the mask-expr and the variable being
4796 defined shall be arrays of the same shape. */
4797 gcc_assert (lss != gfc_ss_terminator);
4799 /* The assignment needs scalarization. */
4800 lss_section = lss;
4802 /* Find a non-scalar SS from the lhs. */
4803 while (lss_section != gfc_ss_terminator
4804 && lss_section->info->type != GFC_SS_SECTION)
4805 lss_section = lss_section->next;
4807 gcc_assert (lss_section != gfc_ss_terminator);
4809 /* Initialize the scalarizer. */
4810 gfc_init_loopinfo (&loop);
4812 /* Walk the rhs. */
4813 rss = gfc_walk_expr (expr2);
4814 if (rss == gfc_ss_terminator)
4816 /* The rhs is scalar. Add a ss for the expression. */
4817 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4818 rss->info->where = 1;
4821 /* Associate the SS with the loop. */
4822 gfc_add_ss_to_loop (&loop, lss);
4823 gfc_add_ss_to_loop (&loop, rss);
4825 /* Calculate the bounds of the scalarization. */
4826 gfc_conv_ss_startstride (&loop);
4828 /* Resolve any data dependencies in the statement. */
4829 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4831 /* Setup the scalarizing loops. */
4832 gfc_conv_loop_setup (&loop, &expr2->where);
4834 /* Setup the gfc_se structures. */
4835 gfc_copy_loopinfo_to_se (&lse, &loop);
4836 gfc_copy_loopinfo_to_se (&rse, &loop);
4838 rse.ss = rss;
4839 gfc_mark_ss_chain_used (rss, 1);
4840 if (loop.temp_ss == NULL)
4842 lse.ss = lss;
4843 gfc_mark_ss_chain_used (lss, 1);
4845 else
4847 lse.ss = loop.temp_ss;
4848 gfc_mark_ss_chain_used (lss, 3);
4849 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4852 /* Start the scalarized loop body. */
4853 gfc_start_scalarized_body (&loop, &body);
4855 /* Translate the expression. */
4856 gfc_conv_expr (&rse, expr2);
4857 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4858 gfc_conv_tmp_array_ref (&lse);
4859 else
4860 gfc_conv_expr (&lse, expr1);
4862 /* Form the mask expression according to the mask. */
4863 index = count1;
4864 maskexpr = gfc_build_array_ref (mask, index, NULL);
4865 if (invert)
4866 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4867 TREE_TYPE (maskexpr), maskexpr);
4869 /* Use the scalar assignment as is. */
4870 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4871 false, loop.temp_ss == NULL);
4873 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4875 gfc_add_expr_to_block (&body, tmp);
4877 if (lss == gfc_ss_terminator)
4879 /* Increment count1. */
4880 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4881 count1, gfc_index_one_node);
4882 gfc_add_modify (&body, count1, tmp);
4884 /* Use the scalar assignment as is. */
4885 gfc_add_block_to_block (&block, &body);
4887 else
4889 gcc_assert (lse.ss == gfc_ss_terminator
4890 && rse.ss == gfc_ss_terminator);
4892 if (loop.temp_ss != NULL)
4894 /* Increment count1 before finish the main body of a scalarized
4895 expression. */
4896 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4897 gfc_array_index_type, count1, gfc_index_one_node);
4898 gfc_add_modify (&body, count1, tmp);
4899 gfc_trans_scalarized_loop_boundary (&loop, &body);
4901 /* We need to copy the temporary to the actual lhs. */
4902 gfc_init_se (&lse, NULL);
4903 gfc_init_se (&rse, NULL);
4904 gfc_copy_loopinfo_to_se (&lse, &loop);
4905 gfc_copy_loopinfo_to_se (&rse, &loop);
4907 rse.ss = loop.temp_ss;
4908 lse.ss = lss;
4910 gfc_conv_tmp_array_ref (&rse);
4911 gfc_conv_expr (&lse, expr1);
4913 gcc_assert (lse.ss == gfc_ss_terminator
4914 && rse.ss == gfc_ss_terminator);
4916 /* Form the mask expression according to the mask tree list. */
4917 index = count2;
4918 maskexpr = gfc_build_array_ref (mask, index, NULL);
4919 if (invert)
4920 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4921 TREE_TYPE (maskexpr), maskexpr);
4923 /* Use the scalar assignment as is. */
4924 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
4925 tmp = build3_v (COND_EXPR, maskexpr, tmp,
4926 build_empty_stmt (input_location));
4927 gfc_add_expr_to_block (&body, tmp);
4929 /* Increment count2. */
4930 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4931 gfc_array_index_type, count2,
4932 gfc_index_one_node);
4933 gfc_add_modify (&body, count2, tmp);
4935 else
4937 /* Increment count1. */
4938 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4939 gfc_array_index_type, count1,
4940 gfc_index_one_node);
4941 gfc_add_modify (&body, count1, tmp);
4944 /* Generate the copying loops. */
4945 gfc_trans_scalarizing_loops (&loop, &body);
4947 /* Wrap the whole thing up. */
4948 gfc_add_block_to_block (&block, &loop.pre);
4949 gfc_add_block_to_block (&block, &loop.post);
4950 gfc_cleanup_loop (&loop);
4953 return gfc_finish_block (&block);
4957 /* Translate the WHERE construct or statement.
4958 This function can be called iteratively to translate the nested WHERE
4959 construct or statement.
4960 MASK is the control mask. */
4962 static void
4963 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4964 forall_info * nested_forall_info, stmtblock_t * block)
4966 stmtblock_t inner_size_body;
4967 tree inner_size, size;
4968 gfc_ss *lss, *rss;
4969 tree mask_type;
4970 gfc_expr *expr1;
4971 gfc_expr *expr2;
4972 gfc_code *cblock;
4973 gfc_code *cnext;
4974 tree tmp;
4975 tree cond;
4976 tree count1, count2;
4977 bool need_cmask;
4978 bool need_pmask;
4979 int need_temp;
4980 tree pcmask = NULL_TREE;
4981 tree ppmask = NULL_TREE;
4982 tree cmask = NULL_TREE;
4983 tree pmask = NULL_TREE;
4984 gfc_actual_arglist *arg;
4986 /* the WHERE statement or the WHERE construct statement. */
4987 cblock = code->block;
4989 /* As the mask array can be very big, prefer compact boolean types. */
4990 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4992 /* Determine which temporary masks are needed. */
4993 if (!cblock->block)
4995 /* One clause: No ELSEWHEREs. */
4996 need_cmask = (cblock->next != 0);
4997 need_pmask = false;
4999 else if (cblock->block->block)
5001 /* Three or more clauses: Conditional ELSEWHEREs. */
5002 need_cmask = true;
5003 need_pmask = true;
5005 else if (cblock->next)
5007 /* Two clauses, the first non-empty. */
5008 need_cmask = true;
5009 need_pmask = (mask != NULL_TREE
5010 && cblock->block->next != 0);
5012 else if (!cblock->block->next)
5014 /* Two clauses, both empty. */
5015 need_cmask = false;
5016 need_pmask = false;
5018 /* Two clauses, the first empty, the second non-empty. */
5019 else if (mask)
5021 need_cmask = (cblock->block->expr1 != 0);
5022 need_pmask = true;
5024 else
5026 need_cmask = true;
5027 need_pmask = false;
5030 if (need_cmask || need_pmask)
5032 /* Calculate the size of temporary needed by the mask-expr. */
5033 gfc_init_block (&inner_size_body);
5034 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5035 &inner_size_body, &lss, &rss);
5037 gfc_free_ss_chain (lss);
5038 gfc_free_ss_chain (rss);
5040 /* Calculate the total size of temporary needed. */
5041 size = compute_overall_iter_number (nested_forall_info, inner_size,
5042 &inner_size_body, block);
5044 /* Check whether the size is negative. */
5045 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, size,
5046 gfc_index_zero_node);
5047 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5048 cond, gfc_index_zero_node, size);
5049 size = gfc_evaluate_now (size, block);
5051 /* Allocate temporary for WHERE mask if needed. */
5052 if (need_cmask)
5053 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5054 &pcmask);
5056 /* Allocate temporary for !mask if needed. */
5057 if (need_pmask)
5058 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5059 &ppmask);
5062 while (cblock)
5064 /* Each time around this loop, the where clause is conditional
5065 on the value of mask and invert, which are updated at the
5066 bottom of the loop. */
5068 /* Has mask-expr. */
5069 if (cblock->expr1)
5071 /* Ensure that the WHERE mask will be evaluated exactly once.
5072 If there are no statements in this WHERE/ELSEWHERE clause,
5073 then we don't need to update the control mask (cmask).
5074 If this is the last clause of the WHERE construct, then
5075 we don't need to update the pending control mask (pmask). */
5076 if (mask)
5077 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5078 mask, invert,
5079 cblock->next ? cmask : NULL_TREE,
5080 cblock->block ? pmask : NULL_TREE,
5081 mask_type, block);
5082 else
5083 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5084 NULL_TREE, false,
5085 (cblock->next || cblock->block)
5086 ? cmask : NULL_TREE,
5087 NULL_TREE, mask_type, block);
5089 invert = false;
5091 /* It's a final elsewhere-stmt. No mask-expr is present. */
5092 else
5093 cmask = mask;
5095 /* The body of this where clause are controlled by cmask with
5096 sense specified by invert. */
5098 /* Get the assignment statement of a WHERE statement, or the first
5099 statement in where-body-construct of a WHERE construct. */
5100 cnext = cblock->next;
5101 while (cnext)
5103 switch (cnext->op)
5105 /* WHERE assignment statement. */
5106 case EXEC_ASSIGN_CALL:
5108 arg = cnext->ext.actual;
5109 expr1 = expr2 = NULL;
5110 for (; arg; arg = arg->next)
5112 if (!arg->expr)
5113 continue;
5114 if (expr1 == NULL)
5115 expr1 = arg->expr;
5116 else
5117 expr2 = arg->expr;
5119 goto evaluate;
5121 case EXEC_ASSIGN:
5122 expr1 = cnext->expr1;
5123 expr2 = cnext->expr2;
5124 evaluate:
5125 if (nested_forall_info != NULL)
5127 need_temp = gfc_check_dependency (expr1, expr2, 0);
5128 if (need_temp && cnext->op != EXEC_ASSIGN_CALL)
5129 gfc_trans_assign_need_temp (expr1, expr2,
5130 cmask, invert,
5131 nested_forall_info, block);
5132 else
5134 /* Variables to control maskexpr. */
5135 count1 = gfc_create_var (gfc_array_index_type, "count1");
5136 count2 = gfc_create_var (gfc_array_index_type, "count2");
5137 gfc_add_modify (block, count1, gfc_index_zero_node);
5138 gfc_add_modify (block, count2, gfc_index_zero_node);
5140 tmp = gfc_trans_where_assign (expr1, expr2,
5141 cmask, invert,
5142 count1, count2,
5143 cnext);
5145 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5146 tmp, 1);
5147 gfc_add_expr_to_block (block, tmp);
5150 else
5152 /* Variables to control maskexpr. */
5153 count1 = gfc_create_var (gfc_array_index_type, "count1");
5154 count2 = gfc_create_var (gfc_array_index_type, "count2");
5155 gfc_add_modify (block, count1, gfc_index_zero_node);
5156 gfc_add_modify (block, count2, gfc_index_zero_node);
5158 tmp = gfc_trans_where_assign (expr1, expr2,
5159 cmask, invert,
5160 count1, count2,
5161 cnext);
5162 gfc_add_expr_to_block (block, tmp);
5165 break;
5167 /* WHERE or WHERE construct is part of a where-body-construct. */
5168 case EXEC_WHERE:
5169 gfc_trans_where_2 (cnext, cmask, invert,
5170 nested_forall_info, block);
5171 break;
5173 default:
5174 gcc_unreachable ();
5177 /* The next statement within the same where-body-construct. */
5178 cnext = cnext->next;
5180 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5181 cblock = cblock->block;
5182 if (mask == NULL_TREE)
5184 /* If we're the initial WHERE, we can simply invert the sense
5185 of the current mask to obtain the "mask" for the remaining
5186 ELSEWHEREs. */
5187 invert = true;
5188 mask = cmask;
5190 else
5192 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5193 invert = false;
5194 mask = pmask;
5198 /* If we allocated a pending mask array, deallocate it now. */
5199 if (ppmask)
5201 tmp = gfc_call_free (ppmask);
5202 gfc_add_expr_to_block (block, tmp);
5205 /* If we allocated a current mask array, deallocate it now. */
5206 if (pcmask)
5208 tmp = gfc_call_free (pcmask);
5209 gfc_add_expr_to_block (block, tmp);
5213 /* Translate a simple WHERE construct or statement without dependencies.
5214 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5215 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5216 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5218 static tree
5219 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5221 stmtblock_t block, body;
5222 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5223 tree tmp, cexpr, tstmt, estmt;
5224 gfc_ss *css, *tdss, *tsss;
5225 gfc_se cse, tdse, tsse, edse, esse;
5226 gfc_loopinfo loop;
5227 gfc_ss *edss = 0;
5228 gfc_ss *esss = 0;
5229 bool maybe_workshare = false;
5231 /* Allow the scalarizer to workshare simple where loops. */
5232 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5233 == OMPWS_WORKSHARE_FLAG)
5235 maybe_workshare = true;
5236 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5239 cond = cblock->expr1;
5240 tdst = cblock->next->expr1;
5241 tsrc = cblock->next->expr2;
5242 edst = eblock ? eblock->next->expr1 : NULL;
5243 esrc = eblock ? eblock->next->expr2 : NULL;
5245 gfc_start_block (&block);
5246 gfc_init_loopinfo (&loop);
5248 /* Handle the condition. */
5249 gfc_init_se (&cse, NULL);
5250 css = gfc_walk_expr (cond);
5251 gfc_add_ss_to_loop (&loop, css);
5253 /* Handle the then-clause. */
5254 gfc_init_se (&tdse, NULL);
5255 gfc_init_se (&tsse, NULL);
5256 tdss = gfc_walk_expr (tdst);
5257 tsss = gfc_walk_expr (tsrc);
5258 if (tsss == gfc_ss_terminator)
5260 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5261 tsss->info->where = 1;
5263 gfc_add_ss_to_loop (&loop, tdss);
5264 gfc_add_ss_to_loop (&loop, tsss);
5266 if (eblock)
5268 /* Handle the else clause. */
5269 gfc_init_se (&edse, NULL);
5270 gfc_init_se (&esse, NULL);
5271 edss = gfc_walk_expr (edst);
5272 esss = gfc_walk_expr (esrc);
5273 if (esss == gfc_ss_terminator)
5275 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5276 esss->info->where = 1;
5278 gfc_add_ss_to_loop (&loop, edss);
5279 gfc_add_ss_to_loop (&loop, esss);
5282 gfc_conv_ss_startstride (&loop);
5283 gfc_conv_loop_setup (&loop, &tdst->where);
5285 gfc_mark_ss_chain_used (css, 1);
5286 gfc_mark_ss_chain_used (tdss, 1);
5287 gfc_mark_ss_chain_used (tsss, 1);
5288 if (eblock)
5290 gfc_mark_ss_chain_used (edss, 1);
5291 gfc_mark_ss_chain_used (esss, 1);
5294 gfc_start_scalarized_body (&loop, &body);
5296 gfc_copy_loopinfo_to_se (&cse, &loop);
5297 gfc_copy_loopinfo_to_se (&tdse, &loop);
5298 gfc_copy_loopinfo_to_se (&tsse, &loop);
5299 cse.ss = css;
5300 tdse.ss = tdss;
5301 tsse.ss = tsss;
5302 if (eblock)
5304 gfc_copy_loopinfo_to_se (&edse, &loop);
5305 gfc_copy_loopinfo_to_se (&esse, &loop);
5306 edse.ss = edss;
5307 esse.ss = esss;
5310 gfc_conv_expr (&cse, cond);
5311 gfc_add_block_to_block (&body, &cse.pre);
5312 cexpr = cse.expr;
5314 gfc_conv_expr (&tsse, tsrc);
5315 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5316 gfc_conv_tmp_array_ref (&tdse);
5317 else
5318 gfc_conv_expr (&tdse, tdst);
5320 if (eblock)
5322 gfc_conv_expr (&esse, esrc);
5323 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5324 gfc_conv_tmp_array_ref (&edse);
5325 else
5326 gfc_conv_expr (&edse, edst);
5329 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5330 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5331 false, true)
5332 : build_empty_stmt (input_location);
5333 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5334 gfc_add_expr_to_block (&body, tmp);
5335 gfc_add_block_to_block (&body, &cse.post);
5337 if (maybe_workshare)
5338 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
5339 gfc_trans_scalarizing_loops (&loop, &body);
5340 gfc_add_block_to_block (&block, &loop.pre);
5341 gfc_add_block_to_block (&block, &loop.post);
5342 gfc_cleanup_loop (&loop);
5344 return gfc_finish_block (&block);
5347 /* As the WHERE or WHERE construct statement can be nested, we call
5348 gfc_trans_where_2 to do the translation, and pass the initial
5349 NULL values for both the control mask and the pending control mask. */
5351 tree
5352 gfc_trans_where (gfc_code * code)
5354 stmtblock_t block;
5355 gfc_code *cblock;
5356 gfc_code *eblock;
5358 cblock = code->block;
5359 if (cblock->next
5360 && cblock->next->op == EXEC_ASSIGN
5361 && !cblock->next->next)
5363 eblock = cblock->block;
5364 if (!eblock)
5366 /* A simple "WHERE (cond) x = y" statement or block is
5367 dependence free if cond is not dependent upon writing x,
5368 and the source y is unaffected by the destination x. */
5369 if (!gfc_check_dependency (cblock->next->expr1,
5370 cblock->expr1, 0)
5371 && !gfc_check_dependency (cblock->next->expr1,
5372 cblock->next->expr2, 0))
5373 return gfc_trans_where_3 (cblock, NULL);
5375 else if (!eblock->expr1
5376 && !eblock->block
5377 && eblock->next
5378 && eblock->next->op == EXEC_ASSIGN
5379 && !eblock->next->next)
5381 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5382 block is dependence free if cond is not dependent on writes
5383 to x1 and x2, y1 is not dependent on writes to x2, and y2
5384 is not dependent on writes to x1, and both y's are not
5385 dependent upon their own x's. In addition to this, the
5386 final two dependency checks below exclude all but the same
5387 array reference if the where and elswhere destinations
5388 are the same. In short, this is VERY conservative and this
5389 is needed because the two loops, required by the standard
5390 are coalesced in gfc_trans_where_3. */
5391 if (!gfc_check_dependency (cblock->next->expr1,
5392 cblock->expr1, 0)
5393 && !gfc_check_dependency (eblock->next->expr1,
5394 cblock->expr1, 0)
5395 && !gfc_check_dependency (cblock->next->expr1,
5396 eblock->next->expr2, 1)
5397 && !gfc_check_dependency (eblock->next->expr1,
5398 cblock->next->expr2, 1)
5399 && !gfc_check_dependency (cblock->next->expr1,
5400 cblock->next->expr2, 1)
5401 && !gfc_check_dependency (eblock->next->expr1,
5402 eblock->next->expr2, 1)
5403 && !gfc_check_dependency (cblock->next->expr1,
5404 eblock->next->expr1, 0)
5405 && !gfc_check_dependency (eblock->next->expr1,
5406 cblock->next->expr1, 0))
5407 return gfc_trans_where_3 (cblock, eblock);
5411 gfc_start_block (&block);
5413 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5415 return gfc_finish_block (&block);
5419 /* CYCLE a DO loop. The label decl has already been created by
5420 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5421 node at the head of the loop. We must mark the label as used. */
5423 tree
5424 gfc_trans_cycle (gfc_code * code)
5426 tree cycle_label;
5428 cycle_label = code->ext.which_construct->cycle_label;
5429 gcc_assert (cycle_label);
5431 TREE_USED (cycle_label) = 1;
5432 return build1_v (GOTO_EXPR, cycle_label);
5436 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5437 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5438 loop. */
5440 tree
5441 gfc_trans_exit (gfc_code * code)
5443 tree exit_label;
5445 exit_label = code->ext.which_construct->exit_label;
5446 gcc_assert (exit_label);
5448 TREE_USED (exit_label) = 1;
5449 return build1_v (GOTO_EXPR, exit_label);
5453 /* Get the initializer expression for the code and expr of an allocate.
5454 When no initializer is needed return NULL. */
5456 static gfc_expr *
5457 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5459 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5460 return NULL;
5462 /* An explicit type was given in allocate ( T:: object). */
5463 if (code->ext.alloc.ts.type == BT_DERIVED
5464 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5465 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5466 return gfc_default_initializer (&code->ext.alloc.ts);
5468 if (gfc_bt_struct (expr->ts.type)
5469 && (expr->ts.u.derived->attr.alloc_comp
5470 || gfc_has_default_initializer (expr->ts.u.derived)))
5471 return gfc_default_initializer (&expr->ts);
5473 if (expr->ts.type == BT_CLASS
5474 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5475 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5476 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5478 return NULL;
5481 /* Translate the ALLOCATE statement. */
5483 tree
5484 gfc_trans_allocate (gfc_code * code)
5486 gfc_alloc *al;
5487 gfc_expr *expr, *e3rhs = NULL, *init_expr;
5488 gfc_se se, se_sz;
5489 tree tmp;
5490 tree parm;
5491 tree stat;
5492 tree errmsg;
5493 tree errlen;
5494 tree label_errmsg;
5495 tree label_finish;
5496 tree memsz;
5497 tree al_vptr, al_len;
5498 /* If an expr3 is present, then store the tree for accessing its
5499 _vptr, and _len components in the variables, respectively. The
5500 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5501 the trees may be the NULL_TREE indicating that this is not
5502 available for expr3's type. */
5503 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5504 /* Classify what expr3 stores. */
5505 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5506 stmtblock_t block;
5507 stmtblock_t post;
5508 tree nelems;
5509 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
5510 gfc_symtree *newsym = NULL;
5512 if (!code->ext.alloc.list)
5513 return NULL_TREE;
5515 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5516 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5517 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5518 e3_is = E3_UNSET;
5520 gfc_init_block (&block);
5521 gfc_init_block (&post);
5523 /* STAT= (and maybe ERRMSG=) is present. */
5524 if (code->expr1)
5526 /* STAT=. */
5527 tree gfc_int4_type_node = gfc_get_int_type (4);
5528 stat = gfc_create_var (gfc_int4_type_node, "stat");
5530 /* ERRMSG= only makes sense with STAT=. */
5531 if (code->expr2)
5533 gfc_init_se (&se, NULL);
5534 se.want_pointer = 1;
5535 gfc_conv_expr_lhs (&se, code->expr2);
5536 errmsg = se.expr;
5537 errlen = se.string_length;
5539 else
5541 errmsg = null_pointer_node;
5542 errlen = build_int_cst (gfc_charlen_type_node, 0);
5545 /* GOTO destinations. */
5546 label_errmsg = gfc_build_label_decl (NULL_TREE);
5547 label_finish = gfc_build_label_decl (NULL_TREE);
5548 TREE_USED (label_finish) = 0;
5551 /* When an expr3 is present evaluate it only once. The standards prevent a
5552 dependency of expr3 on the objects in the allocate list. An expr3 can
5553 be pre-evaluated in all cases. One just has to make sure, to use the
5554 correct way, i.e., to get the descriptor or to get a reference
5555 expression. */
5556 if (code->expr3)
5558 bool vtab_needed = false, temp_var_needed = false,
5559 is_coarray = gfc_is_coarray (code->expr3);
5561 /* Figure whether we need the vtab from expr3. */
5562 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5563 al = al->next)
5564 vtab_needed = (al->expr->ts.type == BT_CLASS);
5566 gfc_init_se (&se, NULL);
5567 /* When expr3 is a variable, i.e., a very simple expression,
5568 then convert it once here. */
5569 if (code->expr3->expr_type == EXPR_VARIABLE
5570 || code->expr3->expr_type == EXPR_ARRAY
5571 || code->expr3->expr_type == EXPR_CONSTANT)
5573 if (!code->expr3->mold
5574 || code->expr3->ts.type == BT_CHARACTER
5575 || vtab_needed
5576 || code->ext.alloc.arr_spec_from_expr3)
5578 /* Convert expr3 to a tree. For all "simple" expression just
5579 get the descriptor or the reference, respectively, depending
5580 on the rank of the expr. */
5581 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5582 gfc_conv_expr_descriptor (&se, code->expr3);
5583 else
5585 gfc_conv_expr_reference (&se, code->expr3);
5587 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5588 NOP_EXPR, which prevents gfortran from getting the vptr
5589 from the source=-expression. Remove the NOP_EXPR and go
5590 with the POINTER_PLUS_EXPR in this case. */
5591 if (code->expr3->ts.type == BT_CLASS
5592 && TREE_CODE (se.expr) == NOP_EXPR
5593 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5594 == POINTER_PLUS_EXPR
5595 || is_coarray))
5596 se.expr = TREE_OPERAND (se.expr, 0);
5598 /* Create a temp variable only for component refs to prevent
5599 having to go through the full deref-chain each time and to
5600 simplfy computation of array properties. */
5601 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5604 else
5606 /* In all other cases evaluate the expr3. */
5607 symbol_attribute attr;
5608 /* Get the descriptor for all arrays, that are not allocatable or
5609 pointer, because the latter are descriptors already.
5610 The exception are function calls returning a class object:
5611 The descriptor is stored in their results _data component, which
5612 is easier to access, when first a temporary variable for the
5613 result is created and the descriptor retrieved from there. */
5614 attr = gfc_expr_attr (code->expr3);
5615 if (code->expr3->rank != 0
5616 && ((!attr.allocatable && !attr.pointer)
5617 || (code->expr3->expr_type == EXPR_FUNCTION
5618 && (code->expr3->ts.type != BT_CLASS
5619 || (code->expr3->value.function.isym
5620 && code->expr3->value.function.isym
5621 ->transformational)))))
5622 gfc_conv_expr_descriptor (&se, code->expr3);
5623 else
5624 gfc_conv_expr_reference (&se, code->expr3);
5625 if (code->expr3->ts.type == BT_CLASS)
5626 gfc_conv_class_to_class (&se, code->expr3,
5627 code->expr3->ts,
5628 false, true,
5629 false, false);
5630 temp_var_needed = !VAR_P (se.expr);
5632 gfc_add_block_to_block (&block, &se.pre);
5633 gfc_add_block_to_block (&post, &se.post);
5635 /* Special case when string in expr3 is zero. */
5636 if (code->expr3->ts.type == BT_CHARACTER
5637 && integer_zerop (se.string_length))
5639 gfc_init_se (&se, NULL);
5640 temp_var_needed = false;
5641 expr3_len = integer_zero_node;
5642 e3_is = E3_MOLD;
5644 /* Prevent aliasing, i.e., se.expr may be already a
5645 variable declaration. */
5646 else if (se.expr != NULL_TREE && temp_var_needed)
5648 tree var, desc;
5649 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5650 se.expr
5651 : build_fold_indirect_ref_loc (input_location, se.expr);
5653 /* Get the array descriptor and prepare it to be assigned to the
5654 temporary variable var. For classes the array descriptor is
5655 in the _data component and the object goes into the
5656 GFC_DECL_SAVED_DESCRIPTOR. */
5657 if (code->expr3->ts.type == BT_CLASS
5658 && code->expr3->rank != 0)
5660 /* When an array_ref was in expr3, then the descriptor is the
5661 first operand. */
5662 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5664 desc = TREE_OPERAND (tmp, 0);
5666 else
5668 desc = tmp;
5669 tmp = gfc_class_data_get (tmp);
5671 if (code->ext.alloc.arr_spec_from_expr3)
5672 e3_is = E3_DESC;
5674 else
5675 desc = !is_coarray ? se.expr
5676 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5677 /* We need a regular (non-UID) symbol here, therefore give a
5678 prefix. */
5679 var = gfc_create_var (TREE_TYPE (tmp), "source");
5680 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5682 gfc_allocate_lang_decl (var);
5683 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5685 gfc_add_modify_loc (input_location, &block, var, tmp);
5687 /* Deallocate any allocatable components after all the allocations
5688 and assignments of expr3 have been completed. */
5689 if (code->expr3->ts.type == BT_DERIVED
5690 && code->expr3->rank == 0
5691 && code->expr3->ts.u.derived->attr.alloc_comp)
5693 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5694 var, 0);
5695 gfc_add_expr_to_block (&post, tmp);
5698 expr3 = var;
5699 if (se.string_length)
5700 /* Evaluate it assuming that it also is complicated like expr3. */
5701 expr3_len = gfc_evaluate_now (se.string_length, &block);
5703 else
5705 expr3 = se.expr;
5706 expr3_len = se.string_length;
5708 /* Store what the expr3 is to be used for. */
5709 if (e3_is == E3_UNSET)
5710 e3_is = expr3 != NULL_TREE ?
5711 (code->ext.alloc.arr_spec_from_expr3 ?
5712 E3_DESC
5713 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
5714 : E3_UNSET;
5716 /* Figure how to get the _vtab entry. This also obtains the tree
5717 expression for accessing the _len component, because only
5718 unlimited polymorphic objects, which are a subcategory of class
5719 types, have a _len component. */
5720 if (code->expr3->ts.type == BT_CLASS)
5722 gfc_expr *rhs;
5723 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
5724 build_fold_indirect_ref (expr3): expr3;
5725 /* Polymorphic SOURCE: VPTR must be determined at run time.
5726 expr3 may be a temporary array declaration, therefore check for
5727 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5728 if (tmp != NULL_TREE
5729 && (e3_is == E3_DESC
5730 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
5731 && (VAR_P (tmp) || !code->expr3->ref))
5732 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
5733 tmp = gfc_class_vptr_get (expr3);
5734 else
5736 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5737 gfc_add_vptr_component (rhs);
5738 gfc_init_se (&se, NULL);
5739 se.want_pointer = 1;
5740 gfc_conv_expr (&se, rhs);
5741 tmp = se.expr;
5742 gfc_free_expr (rhs);
5744 /* Set the element size. */
5745 expr3_esize = gfc_vptr_size_get (tmp);
5746 if (vtab_needed)
5747 expr3_vptr = tmp;
5748 /* Initialize the ref to the _len component. */
5749 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5751 /* Same like for retrieving the _vptr. */
5752 if (expr3 != NULL_TREE && !code->expr3->ref)
5753 expr3_len = gfc_class_len_get (expr3);
5754 else
5756 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5757 gfc_add_len_component (rhs);
5758 gfc_init_se (&se, NULL);
5759 gfc_conv_expr (&se, rhs);
5760 expr3_len = se.expr;
5761 gfc_free_expr (rhs);
5765 else
5767 /* When the object to allocate is polymorphic type, then it
5768 needs its vtab set correctly, so deduce the required _vtab
5769 and _len from the source expression. */
5770 if (vtab_needed)
5772 /* VPTR is fixed at compile time. */
5773 gfc_symbol *vtab;
5775 vtab = gfc_find_vtab (&code->expr3->ts);
5776 gcc_assert (vtab);
5777 expr3_vptr = gfc_get_symbol_decl (vtab);
5778 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5779 expr3_vptr);
5781 /* _len component needs to be set, when ts is a character
5782 array. */
5783 if (expr3_len == NULL_TREE
5784 && code->expr3->ts.type == BT_CHARACTER)
5786 if (code->expr3->ts.u.cl
5787 && code->expr3->ts.u.cl->length)
5789 gfc_init_se (&se, NULL);
5790 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5791 gfc_add_block_to_block (&block, &se.pre);
5792 expr3_len = gfc_evaluate_now (se.expr, &block);
5794 gcc_assert (expr3_len);
5796 /* For character arrays only the kind's size is needed, because
5797 the array mem_size is _len * (elem_size = kind_size).
5798 For all other get the element size in the normal way. */
5799 if (code->expr3->ts.type == BT_CHARACTER)
5800 expr3_esize = TYPE_SIZE_UNIT (
5801 gfc_get_char_type (code->expr3->ts.kind));
5802 else
5803 expr3_esize = TYPE_SIZE_UNIT (
5804 gfc_typenode_for_spec (&code->expr3->ts));
5806 gcc_assert (expr3_esize);
5807 expr3_esize = fold_convert (sizetype, expr3_esize);
5808 if (e3_is == E3_MOLD)
5809 /* The expr3 is no longer valid after this point. */
5810 expr3 = NULL_TREE;
5812 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5814 /* Compute the explicit typespec given only once for all objects
5815 to allocate. */
5816 if (code->ext.alloc.ts.type != BT_CHARACTER)
5817 expr3_esize = TYPE_SIZE_UNIT (
5818 gfc_typenode_for_spec (&code->ext.alloc.ts));
5819 else
5821 gfc_expr *sz;
5822 gcc_assert (code->ext.alloc.ts.u.cl->length != NULL);
5823 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5824 gfc_init_se (&se_sz, NULL);
5825 gfc_conv_expr (&se_sz, sz);
5826 gfc_free_expr (sz);
5827 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5828 tmp = TYPE_SIZE_UNIT (tmp);
5829 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5830 gfc_add_block_to_block (&block, &se_sz.pre);
5831 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5832 TREE_TYPE (se_sz.expr),
5833 tmp, se_sz.expr);
5834 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
5838 /* The routine gfc_trans_assignment () already implements all
5839 techniques needed. Unfortunately we may have a temporary
5840 variable for the source= expression here. When that is the
5841 case convert this variable into a temporary gfc_expr of type
5842 EXPR_VARIABLE and used it as rhs for the assignment. The
5843 advantage is, that we get scalarizer support for free,
5844 don't have to take care about scalar to array treatment and
5845 will benefit of every enhancements gfc_trans_assignment ()
5846 gets.
5847 No need to check whether e3_is is E3_UNSET, because that is
5848 done by expr3 != NULL_TREE.
5849 Exclude variables since the following block does not handle
5850 array sections. In any case, there is no harm in sending
5851 variables to gfc_trans_assignment because there is no
5852 evaluation of variables. */
5853 if (code->expr3)
5855 if (code->expr3->expr_type != EXPR_VARIABLE
5856 && e3_is != E3_MOLD && expr3 != NULL_TREE
5857 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
5859 /* Build a temporary symtree and symbol. Do not add it to the current
5860 namespace to prevent accidently modifying a colliding
5861 symbol's as. */
5862 newsym = XCNEW (gfc_symtree);
5863 /* The name of the symtree should be unique, because gfc_create_var ()
5864 took care about generating the identifier. */
5865 newsym->name = gfc_get_string (IDENTIFIER_POINTER (
5866 DECL_NAME (expr3)));
5867 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
5868 /* The backend_decl is known. It is expr3, which is inserted
5869 here. */
5870 newsym->n.sym->backend_decl = expr3;
5871 e3rhs = gfc_get_expr ();
5872 e3rhs->rank = code->expr3->rank;
5873 e3rhs->symtree = newsym;
5874 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
5875 newsym->n.sym->attr.referenced = 1;
5876 e3rhs->expr_type = EXPR_VARIABLE;
5877 e3rhs->where = code->expr3->where;
5878 /* Set the symbols type, upto it was BT_UNKNOWN. */
5879 if (IS_CLASS_ARRAY (code->expr3)
5880 && code->expr3->expr_type == EXPR_FUNCTION
5881 && code->expr3->value.function.isym
5882 && code->expr3->value.function.isym->transformational)
5884 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
5886 else if (code->expr3->ts.type == BT_CLASS
5887 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
5888 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
5889 else
5890 e3rhs->ts = code->expr3->ts;
5891 newsym->n.sym->ts = e3rhs->ts;
5892 /* Check whether the expr3 is array valued. */
5893 if (e3rhs->rank)
5895 gfc_array_spec *arr;
5896 arr = gfc_get_array_spec ();
5897 arr->rank = e3rhs->rank;
5898 arr->type = AS_DEFERRED;
5899 /* Set the dimension and pointer attribute for arrays
5900 to be on the safe side. */
5901 newsym->n.sym->attr.dimension = 1;
5902 newsym->n.sym->attr.pointer = 1;
5903 newsym->n.sym->as = arr;
5904 if (IS_CLASS_ARRAY (code->expr3)
5905 && code->expr3->expr_type == EXPR_FUNCTION
5906 && code->expr3->value.function.isym
5907 && code->expr3->value.function.isym->transformational)
5909 gfc_array_spec *tarr;
5910 tarr = gfc_get_array_spec ();
5911 *tarr = *arr;
5912 e3rhs->ts.u.derived->as = tarr;
5914 gfc_add_full_array_ref (e3rhs, arr);
5916 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
5917 newsym->n.sym->attr.pointer = 1;
5918 /* The string length is known, too. Set it for char arrays. */
5919 if (e3rhs->ts.type == BT_CHARACTER)
5920 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
5921 gfc_commit_symbol (newsym->n.sym);
5923 else
5924 e3rhs = gfc_copy_expr (code->expr3);
5927 /* Loop over all objects to allocate. */
5928 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5930 expr = gfc_copy_expr (al->expr);
5931 /* UNLIMITED_POLY () needs the _data component to be set, when
5932 expr is a unlimited polymorphic object. But the _data component
5933 has not been set yet, so check the derived type's attr for the
5934 unlimited polymorphic flag to be safe. */
5935 upoly_expr = UNLIMITED_POLY (expr)
5936 || (expr->ts.type == BT_DERIVED
5937 && expr->ts.u.derived->attr.unlimited_polymorphic);
5938 gfc_init_se (&se, NULL);
5940 /* For class types prepare the expressions to ref the _vptr
5941 and the _len component. The latter for unlimited polymorphic
5942 types only. */
5943 if (expr->ts.type == BT_CLASS)
5945 gfc_expr *expr_ref_vptr, *expr_ref_len;
5946 gfc_add_data_component (expr);
5947 /* Prep the vptr handle. */
5948 expr_ref_vptr = gfc_copy_expr (al->expr);
5949 gfc_add_vptr_component (expr_ref_vptr);
5950 se.want_pointer = 1;
5951 gfc_conv_expr (&se, expr_ref_vptr);
5952 al_vptr = se.expr;
5953 se.want_pointer = 0;
5954 gfc_free_expr (expr_ref_vptr);
5955 /* Allocated unlimited polymorphic objects always have a _len
5956 component. */
5957 if (upoly_expr)
5959 expr_ref_len = gfc_copy_expr (al->expr);
5960 gfc_add_len_component (expr_ref_len);
5961 gfc_conv_expr (&se, expr_ref_len);
5962 al_len = se.expr;
5963 gfc_free_expr (expr_ref_len);
5965 else
5966 /* In a loop ensure that all loop variable dependent variables
5967 are initialized at the same spot in all execution paths. */
5968 al_len = NULL_TREE;
5970 else
5971 al_vptr = al_len = NULL_TREE;
5973 se.want_pointer = 1;
5974 se.descriptor_only = 1;
5976 gfc_conv_expr (&se, expr);
5977 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5978 /* se.string_length now stores the .string_length variable of expr
5979 needed to allocate character(len=:) arrays. */
5980 al_len = se.string_length;
5982 al_len_needs_set = al_len != NULL_TREE;
5983 /* When allocating an array one can not use much of the
5984 pre-evaluated expr3 expressions, because for most of them the
5985 scalarizer is needed which is not available in the pre-evaluation
5986 step. Therefore gfc_array_allocate () is responsible (and able)
5987 to handle the complete array allocation. Only the element size
5988 needs to be provided, which is done most of the time by the
5989 pre-evaluation step. */
5990 nelems = NULL_TREE;
5991 if (expr3_len && code->expr3->ts.type == BT_CHARACTER)
5992 /* When al is an array, then the element size for each element
5993 in the array is needed, which is the product of the len and
5994 esize for char arrays. */
5995 tmp = fold_build2_loc (input_location, MULT_EXPR,
5996 TREE_TYPE (expr3_esize), expr3_esize,
5997 fold_convert (TREE_TYPE (expr3_esize),
5998 expr3_len));
5999 else
6000 tmp = expr3_esize;
6001 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6002 label_finish, tmp, &nelems,
6003 e3rhs ? e3rhs : code->expr3,
6004 e3_is == E3_DESC ? expr3 : NULL_TREE,
6005 code->expr3 != NULL && e3_is == E3_DESC
6006 && code->expr3->expr_type == EXPR_ARRAY))
6008 /* A scalar or derived type. First compute the size to
6009 allocate.
6011 expr3_len is set when expr3 is an unlimited polymorphic
6012 object or a deferred length string. */
6013 if (expr3_len != NULL_TREE)
6015 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6016 tmp = fold_build2_loc (input_location, MULT_EXPR,
6017 TREE_TYPE (expr3_esize),
6018 expr3_esize, tmp);
6019 if (code->expr3->ts.type != BT_CLASS)
6020 /* expr3 is a deferred length string, i.e., we are
6021 done. */
6022 memsz = tmp;
6023 else
6025 /* For unlimited polymorphic enties build
6026 (len > 0) ? element_size * len : element_size
6027 to compute the number of bytes to allocate.
6028 This allows the allocation of unlimited polymorphic
6029 objects from an expr3 that is also unlimited
6030 polymorphic and stores a _len dependent object,
6031 e.g., a string. */
6032 memsz = fold_build2_loc (input_location, GT_EXPR,
6033 boolean_type_node, expr3_len,
6034 integer_zero_node);
6035 memsz = fold_build3_loc (input_location, COND_EXPR,
6036 TREE_TYPE (expr3_esize),
6037 memsz, tmp, expr3_esize);
6040 else if (expr3_esize != NULL_TREE)
6041 /* Any other object in expr3 just needs element size in
6042 bytes. */
6043 memsz = expr3_esize;
6044 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6045 || (upoly_expr
6046 && code->ext.alloc.ts.type == BT_CHARACTER))
6048 /* Allocating deferred length char arrays need the length
6049 to allocate in the alloc_type_spec. But also unlimited
6050 polymorphic objects may be allocated as char arrays.
6051 Both are handled here. */
6052 gfc_init_se (&se_sz, NULL);
6053 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6054 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6055 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6056 gfc_add_block_to_block (&se.pre, &se_sz.post);
6057 expr3_len = se_sz.expr;
6058 tmp_expr3_len_flag = true;
6059 tmp = TYPE_SIZE_UNIT (
6060 gfc_get_char_type (code->ext.alloc.ts.kind));
6061 memsz = fold_build2_loc (input_location, MULT_EXPR,
6062 TREE_TYPE (tmp),
6063 fold_convert (TREE_TYPE (tmp),
6064 expr3_len),
6065 tmp);
6067 else if (expr->ts.type == BT_CHARACTER)
6069 /* Compute the number of bytes needed to allocate a fixed
6070 length char array. */
6071 gcc_assert (se.string_length != NULL_TREE);
6072 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6073 memsz = fold_build2_loc (input_location, MULT_EXPR,
6074 TREE_TYPE (tmp), tmp,
6075 fold_convert (TREE_TYPE (tmp),
6076 se.string_length));
6078 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6079 /* Handle all types, where the alloc_type_spec is set. */
6080 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6081 else
6082 /* Handle size computation of the type declared to alloc. */
6083 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6085 if (gfc_caf_attr (expr).codimension
6086 && flag_coarray == GFC_FCOARRAY_LIB)
6088 /* Scalar allocatable components in coarray'ed derived types make
6089 it here and are treated now. */
6090 tree caf_decl, token;
6091 gfc_se caf_se;
6093 gfc_init_se (&caf_se, NULL);
6095 caf_decl = gfc_get_tree_for_caf_expr (expr);
6096 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6097 NULL_TREE, NULL);
6098 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6099 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6100 gfc_build_addr_expr (NULL_TREE, token),
6101 NULL_TREE, NULL_TREE, NULL_TREE,
6102 label_finish, expr, 1);
6104 /* Allocate - for non-pointers with re-alloc checking. */
6105 else if (gfc_expr_attr (expr).allocatable)
6106 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6107 NULL_TREE, stat, errmsg, errlen,
6108 label_finish, expr, 0);
6109 else
6110 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6112 else
6114 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6115 && expr3_len != NULL_TREE)
6117 /* Arrays need to have a _len set before the array
6118 descriptor is filled. */
6119 gfc_add_modify (&block, al_len,
6120 fold_convert (TREE_TYPE (al_len), expr3_len));
6121 /* Prevent setting the length twice. */
6122 al_len_needs_set = false;
6124 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6125 && code->ext.alloc.ts.u.cl->length)
6127 /* Cover the cases where a string length is explicitly
6128 specified by a type spec for deferred length character
6129 arrays or unlimited polymorphic objects without a
6130 source= or mold= expression. */
6131 gfc_init_se (&se_sz, NULL);
6132 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6133 gfc_add_block_to_block (&block, &se_sz.pre);
6134 gfc_add_modify (&block, al_len,
6135 fold_convert (TREE_TYPE (al_len),
6136 se_sz.expr));
6137 al_len_needs_set = false;
6141 gfc_add_block_to_block (&block, &se.pre);
6143 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6144 if (code->expr1)
6146 tmp = build1_v (GOTO_EXPR, label_errmsg);
6147 parm = fold_build2_loc (input_location, NE_EXPR,
6148 boolean_type_node, stat,
6149 build_int_cst (TREE_TYPE (stat), 0));
6150 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6151 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6152 tmp, build_empty_stmt (input_location));
6153 gfc_add_expr_to_block (&block, tmp);
6156 /* Set the vptr only when no source= is set. When source= is set, then
6157 the trans_assignment below will set the vptr. */
6158 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6160 if (expr3_vptr != NULL_TREE)
6161 /* The vtab is already known, so just assign it. */
6162 gfc_add_modify (&block, al_vptr,
6163 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6164 else
6166 /* VPTR is fixed at compile time. */
6167 gfc_symbol *vtab;
6168 gfc_typespec *ts;
6170 if (code->expr3)
6171 /* Although expr3 is pre-evaluated above, it may happen,
6172 that for arrays or in mold= cases the pre-evaluation
6173 was not successful. In these rare cases take the vtab
6174 from the typespec of expr3 here. */
6175 ts = &code->expr3->ts;
6176 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6177 /* The alloc_type_spec gives the type to allocate or the
6178 al is unlimited polymorphic, which enforces the use of
6179 an alloc_type_spec that is not necessarily a BT_DERIVED. */
6180 ts = &code->ext.alloc.ts;
6181 else
6182 /* Prepare for setting the vtab as declared. */
6183 ts = &expr->ts;
6185 vtab = gfc_find_vtab (ts);
6186 gcc_assert (vtab);
6187 tmp = gfc_build_addr_expr (NULL_TREE,
6188 gfc_get_symbol_decl (vtab));
6189 gfc_add_modify (&block, al_vptr,
6190 fold_convert (TREE_TYPE (al_vptr), tmp));
6194 /* Add assignment for string length. */
6195 if (al_len != NULL_TREE && al_len_needs_set)
6197 if (expr3_len != NULL_TREE)
6199 gfc_add_modify (&block, al_len,
6200 fold_convert (TREE_TYPE (al_len),
6201 expr3_len));
6202 /* When tmp_expr3_len_flag is set, then expr3_len is
6203 abused to carry the length information from the
6204 alloc_type. Clear it to prevent setting incorrect len
6205 information in future loop iterations. */
6206 if (tmp_expr3_len_flag)
6207 /* No need to reset tmp_expr3_len_flag, because the
6208 presence of an expr3 can not change within in the
6209 loop. */
6210 expr3_len = NULL_TREE;
6212 else if (code->ext.alloc.ts.type == BT_CHARACTER
6213 && code->ext.alloc.ts.u.cl->length)
6215 /* Cover the cases where a string length is explicitly
6216 specified by a type spec for deferred length character
6217 arrays or unlimited polymorphic objects without a
6218 source= or mold= expression. */
6219 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6221 gfc_init_se (&se_sz, NULL);
6222 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6223 gfc_add_block_to_block (&block, &se_sz.pre);
6224 gfc_add_modify (&block, al_len,
6225 fold_convert (TREE_TYPE (al_len),
6226 se_sz.expr));
6228 else
6229 gfc_add_modify (&block, al_len,
6230 fold_convert (TREE_TYPE (al_len),
6231 expr3_esize));
6233 else
6234 /* No length information needed, because type to allocate
6235 has no length. Set _len to 0. */
6236 gfc_add_modify (&block, al_len,
6237 fold_convert (TREE_TYPE (al_len),
6238 integer_zero_node));
6241 init_expr = NULL;
6242 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6244 /* Initialization via SOURCE block (or static default initializer).
6245 Switch off automatic reallocation since we have just done the
6246 ALLOCATE. */
6247 int realloc_lhs = flag_realloc_lhs;
6248 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6249 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6250 flag_realloc_lhs = 0;
6251 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6252 false);
6253 flag_realloc_lhs = realloc_lhs;
6254 /* Free the expression allocated for init_expr. */
6255 gfc_free_expr (init_expr);
6256 if (rhs != e3rhs)
6257 gfc_free_expr (rhs);
6258 gfc_add_expr_to_block (&block, tmp);
6260 else if (code->expr3 && code->expr3->mold
6261 && code->expr3->ts.type == BT_CLASS)
6263 /* Use class_init_assign to initialize expr. */
6264 gfc_code *ini;
6265 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6266 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6267 tmp = gfc_trans_class_init_assign (ini);
6268 gfc_free_statements (ini);
6269 gfc_add_expr_to_block (&block, tmp);
6271 else if ((init_expr = allocate_get_initializer (code, expr)))
6273 /* Use class_init_assign to initialize expr. */
6274 gfc_code *ini;
6275 int realloc_lhs = flag_realloc_lhs;
6276 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6277 ini->expr1 = gfc_expr_to_initialize (expr);
6278 ini->expr2 = init_expr;
6279 flag_realloc_lhs = 0;
6280 tmp= gfc_trans_init_assign (ini);
6281 flag_realloc_lhs = realloc_lhs;
6282 gfc_free_statements (ini);
6283 /* Init_expr is freeed by above free_statements, just need to null
6284 it here. */
6285 init_expr = NULL;
6286 gfc_add_expr_to_block (&block, tmp);
6289 gfc_free_expr (expr);
6290 } // for-loop
6292 if (e3rhs)
6294 if (newsym)
6296 gfc_free_symbol (newsym->n.sym);
6297 XDELETE (newsym);
6299 gfc_free_expr (e3rhs);
6301 /* STAT. */
6302 if (code->expr1)
6304 tmp = build1_v (LABEL_EXPR, label_errmsg);
6305 gfc_add_expr_to_block (&block, tmp);
6308 /* ERRMSG - only useful if STAT is present. */
6309 if (code->expr1 && code->expr2)
6311 const char *msg = "Attempt to allocate an allocated object";
6312 tree slen, dlen, errmsg_str;
6313 stmtblock_t errmsg_block;
6315 gfc_init_block (&errmsg_block);
6317 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6318 gfc_add_modify (&errmsg_block, errmsg_str,
6319 gfc_build_addr_expr (pchar_type_node,
6320 gfc_build_localized_cstring_const (msg)));
6322 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6323 dlen = gfc_get_expr_charlen (code->expr2);
6324 slen = fold_build2_loc (input_location, MIN_EXPR,
6325 TREE_TYPE (slen), dlen, slen);
6327 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6328 code->expr2->ts.kind,
6329 slen, errmsg_str,
6330 gfc_default_character_kind);
6331 dlen = gfc_finish_block (&errmsg_block);
6333 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6334 stat, build_int_cst (TREE_TYPE (stat), 0));
6336 tmp = build3_v (COND_EXPR, tmp,
6337 dlen, build_empty_stmt (input_location));
6339 gfc_add_expr_to_block (&block, tmp);
6342 /* STAT block. */
6343 if (code->expr1)
6345 if (TREE_USED (label_finish))
6347 tmp = build1_v (LABEL_EXPR, label_finish);
6348 gfc_add_expr_to_block (&block, tmp);
6351 gfc_init_se (&se, NULL);
6352 gfc_conv_expr_lhs (&se, code->expr1);
6353 tmp = convert (TREE_TYPE (se.expr), stat);
6354 gfc_add_modify (&block, se.expr, tmp);
6357 gfc_add_block_to_block (&block, &se.post);
6358 gfc_add_block_to_block (&block, &post);
6360 return gfc_finish_block (&block);
6364 /* Translate a DEALLOCATE statement. */
6366 tree
6367 gfc_trans_deallocate (gfc_code *code)
6369 gfc_se se;
6370 gfc_alloc *al;
6371 tree apstat, pstat, stat, errmsg, errlen, tmp;
6372 tree label_finish, label_errmsg;
6373 stmtblock_t block;
6375 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6376 label_finish = label_errmsg = NULL_TREE;
6378 gfc_start_block (&block);
6380 /* Count the number of failed deallocations. If deallocate() was
6381 called with STAT= , then set STAT to the count. If deallocate
6382 was called with ERRMSG, then set ERRMG to a string. */
6383 if (code->expr1)
6385 tree gfc_int4_type_node = gfc_get_int_type (4);
6387 stat = gfc_create_var (gfc_int4_type_node, "stat");
6388 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6390 /* GOTO destinations. */
6391 label_errmsg = gfc_build_label_decl (NULL_TREE);
6392 label_finish = gfc_build_label_decl (NULL_TREE);
6393 TREE_USED (label_finish) = 0;
6396 /* Set ERRMSG - only needed if STAT is available. */
6397 if (code->expr1 && code->expr2)
6399 gfc_init_se (&se, NULL);
6400 se.want_pointer = 1;
6401 gfc_conv_expr_lhs (&se, code->expr2);
6402 errmsg = se.expr;
6403 errlen = se.string_length;
6406 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6408 gfc_expr *expr = gfc_copy_expr (al->expr);
6409 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6411 if (expr->ts.type == BT_CLASS)
6412 gfc_add_data_component (expr);
6414 gfc_init_se (&se, NULL);
6415 gfc_start_block (&se.pre);
6417 se.want_pointer = 1;
6418 se.descriptor_only = 1;
6419 gfc_conv_expr (&se, expr);
6421 if (expr->rank || gfc_caf_attr (expr).codimension)
6423 gfc_ref *ref;
6425 if (gfc_bt_struct (expr->ts.type) && expr->ts.u.derived->attr.alloc_comp
6426 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6428 gfc_ref *last = NULL;
6430 for (ref = expr->ref; ref; ref = ref->next)
6431 if (ref->type == REF_COMPONENT)
6432 last = ref;
6434 /* Do not deallocate the components of a derived type
6435 ultimate pointer component. */
6436 if (!(last && last->u.c.component->attr.pointer)
6437 && !(!last && expr->symtree->n.sym->attr.pointer))
6439 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr,
6440 expr->rank);
6441 gfc_add_expr_to_block (&se.pre, tmp);
6445 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6447 tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen,
6448 label_finish, expr);
6449 gfc_add_expr_to_block (&se.pre, tmp);
6451 else if (TREE_CODE (se.expr) == COMPONENT_REF
6452 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6453 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6454 == RECORD_TYPE)
6456 /* class.c(finalize_component) generates these, when a
6457 finalizable entity has a non-allocatable derived type array
6458 component, which has allocatable components. Obtain the
6459 derived type of the array and deallocate the allocatable
6460 components. */
6461 for (ref = expr->ref; ref; ref = ref->next)
6463 if (ref->u.c.component->attr.dimension
6464 && ref->u.c.component->ts.type == BT_DERIVED)
6465 break;
6468 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6469 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6470 NULL))
6472 tmp = gfc_deallocate_alloc_comp
6473 (ref->u.c.component->ts.u.derived,
6474 se.expr, expr->rank);
6475 gfc_add_expr_to_block (&se.pre, tmp);
6479 if (al->expr->ts.type == BT_CLASS)
6481 gfc_reset_vptr (&se.pre, al->expr);
6482 if (UNLIMITED_POLY (al->expr)
6483 || (al->expr->ts.type == BT_DERIVED
6484 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6485 /* Clear _len, too. */
6486 gfc_reset_len (&se.pre, al->expr);
6489 else
6491 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, false,
6492 al->expr, al->expr->ts);
6493 gfc_add_expr_to_block (&se.pre, tmp);
6495 /* Set to zero after deallocation. */
6496 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6497 se.expr,
6498 build_int_cst (TREE_TYPE (se.expr), 0));
6499 gfc_add_expr_to_block (&se.pre, tmp);
6501 if (al->expr->ts.type == BT_CLASS)
6503 gfc_reset_vptr (&se.pre, al->expr);
6504 if (UNLIMITED_POLY (al->expr)
6505 || (al->expr->ts.type == BT_DERIVED
6506 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6507 /* Clear _len, too. */
6508 gfc_reset_len (&se.pre, al->expr);
6512 if (code->expr1)
6514 tree cond;
6516 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6517 build_int_cst (TREE_TYPE (stat), 0));
6518 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6519 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6520 build1_v (GOTO_EXPR, label_errmsg),
6521 build_empty_stmt (input_location));
6522 gfc_add_expr_to_block (&se.pre, tmp);
6525 tmp = gfc_finish_block (&se.pre);
6526 gfc_add_expr_to_block (&block, tmp);
6527 gfc_free_expr (expr);
6530 if (code->expr1)
6532 tmp = build1_v (LABEL_EXPR, label_errmsg);
6533 gfc_add_expr_to_block (&block, tmp);
6536 /* Set ERRMSG - only needed if STAT is available. */
6537 if (code->expr1 && code->expr2)
6539 const char *msg = "Attempt to deallocate an unallocated object";
6540 stmtblock_t errmsg_block;
6541 tree errmsg_str, slen, dlen, cond;
6543 gfc_init_block (&errmsg_block);
6545 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6546 gfc_add_modify (&errmsg_block, errmsg_str,
6547 gfc_build_addr_expr (pchar_type_node,
6548 gfc_build_localized_cstring_const (msg)));
6549 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6550 dlen = gfc_get_expr_charlen (code->expr2);
6552 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6553 slen, errmsg_str, gfc_default_character_kind);
6554 tmp = gfc_finish_block (&errmsg_block);
6556 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6557 build_int_cst (TREE_TYPE (stat), 0));
6558 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6559 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6560 build_empty_stmt (input_location));
6562 gfc_add_expr_to_block (&block, tmp);
6565 if (code->expr1 && TREE_USED (label_finish))
6567 tmp = build1_v (LABEL_EXPR, label_finish);
6568 gfc_add_expr_to_block (&block, tmp);
6571 /* Set STAT. */
6572 if (code->expr1)
6574 gfc_init_se (&se, NULL);
6575 gfc_conv_expr_lhs (&se, code->expr1);
6576 tmp = convert (TREE_TYPE (se.expr), stat);
6577 gfc_add_modify (&block, se.expr, tmp);
6580 return gfc_finish_block (&block);
6583 #include "gt-fortran-trans-stmt.h"