* tree.c (array_at_struct_end_p): Look through MEM_REF.
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob7d3cf8cae5aef7c449179acfaa8bbf46e9bf8c13
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 (&token, NULL, caf_decl, NULL_TREE, code->expr1);
730 if (gfc_is_coindexed (code->expr1))
731 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
732 else
733 image_index = integer_zero_node;
735 /* For arrays, obtain the array index. */
736 if (gfc_expr_attr (code->expr1).dimension)
738 tree desc, tmp, extent, lbound, ubound;
739 gfc_array_ref *ar, ar2;
740 int i;
742 /* TODO: Extend this, once DT components are supported. */
743 ar = &code->expr1->ref->u.ar;
744 ar2 = *ar;
745 memset (ar, '\0', sizeof (*ar));
746 ar->as = ar2.as;
747 ar->type = AR_FULL;
749 gfc_init_se (&argse, NULL);
750 argse.descriptor_only = 1;
751 gfc_conv_expr_descriptor (&argse, code->expr1);
752 gfc_add_block_to_block (&se.pre, &argse.pre);
753 desc = argse.expr;
754 *ar = ar2;
756 extent = integer_one_node;
757 for (i = 0; i < ar->dimen; i++)
759 gfc_init_se (&argse, NULL);
760 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
761 gfc_add_block_to_block (&argse.pre, &argse.pre);
762 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
763 tmp = fold_build2_loc (input_location, MINUS_EXPR,
764 integer_type_node, argse.expr,
765 fold_convert(integer_type_node, lbound));
766 tmp = fold_build2_loc (input_location, MULT_EXPR,
767 integer_type_node, extent, tmp);
768 index = fold_build2_loc (input_location, PLUS_EXPR,
769 integer_type_node, index, tmp);
770 if (i < ar->dimen - 1)
772 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
773 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
774 tmp = fold_convert (integer_type_node, tmp);
775 extent = fold_build2_loc (input_location, MULT_EXPR,
776 integer_type_node, extent, tmp);
781 /* errmsg. */
782 if (code->expr3)
784 gfc_init_se (&argse, NULL);
785 argse.want_pointer = 1;
786 gfc_conv_expr (&argse, code->expr3);
787 gfc_add_block_to_block (&se.pre, &argse.pre);
788 errmsg = argse.expr;
789 errmsg_len = fold_convert (integer_type_node, argse.string_length);
791 else
793 errmsg = null_pointer_node;
794 errmsg_len = integer_zero_node;
797 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
799 stat2 = stat;
800 stat = gfc_create_var (integer_type_node, "stat");
803 if (lock_acquired != null_pointer_node
804 && TREE_TYPE (lock_acquired) != integer_type_node)
806 lock_acquired2 = lock_acquired;
807 lock_acquired = gfc_create_var (integer_type_node, "acquired");
810 if (op == EXEC_LOCK)
811 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
812 token, index, image_index,
813 lock_acquired != null_pointer_node
814 ? gfc_build_addr_expr (NULL, lock_acquired)
815 : lock_acquired,
816 stat != null_pointer_node
817 ? gfc_build_addr_expr (NULL, stat) : stat,
818 errmsg, errmsg_len);
819 else
820 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
821 token, index, image_index,
822 stat != null_pointer_node
823 ? gfc_build_addr_expr (NULL, stat) : stat,
824 errmsg, errmsg_len);
825 gfc_add_expr_to_block (&se.pre, tmp);
827 /* It guarantees memory consistency within the same segment */
828 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
829 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
830 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
831 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
832 ASM_VOLATILE_P (tmp) = 1;
834 gfc_add_expr_to_block (&se.pre, tmp);
836 if (stat2 != NULL_TREE)
837 gfc_add_modify (&se.pre, stat2,
838 fold_convert (TREE_TYPE (stat2), stat));
840 if (lock_acquired2 != NULL_TREE)
841 gfc_add_modify (&se.pre, lock_acquired2,
842 fold_convert (TREE_TYPE (lock_acquired2),
843 lock_acquired));
845 return gfc_finish_block (&se.pre);
848 if (stat != NULL_TREE)
849 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
851 if (lock_acquired != NULL_TREE)
852 gfc_add_modify (&se.pre, lock_acquired,
853 fold_convert (TREE_TYPE (lock_acquired),
854 boolean_true_node));
856 return gfc_finish_block (&se.pre);
859 tree
860 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
862 gfc_se se, argse;
863 tree stat = NULL_TREE, stat2 = NULL_TREE;
864 tree until_count = NULL_TREE;
866 if (code->expr2)
868 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
869 gfc_init_se (&argse, NULL);
870 gfc_conv_expr_val (&argse, code->expr2);
871 stat = argse.expr;
873 else if (flag_coarray == GFC_FCOARRAY_LIB)
874 stat = null_pointer_node;
876 if (code->expr4)
878 gfc_init_se (&argse, NULL);
879 gfc_conv_expr_val (&argse, code->expr4);
880 until_count = fold_convert (integer_type_node, argse.expr);
882 else
883 until_count = integer_one_node;
885 if (flag_coarray != GFC_FCOARRAY_LIB)
887 gfc_start_block (&se.pre);
888 gfc_init_se (&argse, NULL);
889 gfc_conv_expr_val (&argse, code->expr1);
891 if (op == EXEC_EVENT_POST)
892 gfc_add_modify (&se.pre, argse.expr,
893 fold_build2_loc (input_location, PLUS_EXPR,
894 TREE_TYPE (argse.expr), argse.expr,
895 build_int_cst (TREE_TYPE (argse.expr), 1)));
896 else
897 gfc_add_modify (&se.pre, argse.expr,
898 fold_build2_loc (input_location, MINUS_EXPR,
899 TREE_TYPE (argse.expr), argse.expr,
900 fold_convert (TREE_TYPE (argse.expr),
901 until_count)));
902 if (stat != NULL_TREE)
903 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
905 return gfc_finish_block (&se.pre);
908 gfc_start_block (&se.pre);
909 tree tmp, token, image_index, errmsg, errmsg_len;
910 tree index = size_zero_node;
911 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
913 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
914 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
915 != INTMOD_ISO_FORTRAN_ENV
916 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
917 != ISOFORTRAN_EVENT_TYPE)
919 gfc_error ("Sorry, the event component of derived type at %L is not "
920 "yet supported", &code->expr1->where);
921 return NULL_TREE;
924 gfc_get_caf_token_offset (&token, NULL, caf_decl, NULL_TREE, code->expr1);
926 if (gfc_is_coindexed (code->expr1))
927 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
928 else
929 image_index = integer_zero_node;
931 /* For arrays, obtain the array index. */
932 if (gfc_expr_attr (code->expr1).dimension)
934 tree desc, tmp, extent, lbound, ubound;
935 gfc_array_ref *ar, ar2;
936 int i;
938 /* TODO: Extend this, once DT components are supported. */
939 ar = &code->expr1->ref->u.ar;
940 ar2 = *ar;
941 memset (ar, '\0', sizeof (*ar));
942 ar->as = ar2.as;
943 ar->type = AR_FULL;
945 gfc_init_se (&argse, NULL);
946 argse.descriptor_only = 1;
947 gfc_conv_expr_descriptor (&argse, code->expr1);
948 gfc_add_block_to_block (&se.pre, &argse.pre);
949 desc = argse.expr;
950 *ar = ar2;
952 extent = integer_one_node;
953 for (i = 0; i < ar->dimen; i++)
955 gfc_init_se (&argse, NULL);
956 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
957 gfc_add_block_to_block (&argse.pre, &argse.pre);
958 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
959 tmp = fold_build2_loc (input_location, MINUS_EXPR,
960 integer_type_node, argse.expr,
961 fold_convert(integer_type_node, lbound));
962 tmp = fold_build2_loc (input_location, MULT_EXPR,
963 integer_type_node, extent, tmp);
964 index = fold_build2_loc (input_location, PLUS_EXPR,
965 integer_type_node, index, tmp);
966 if (i < ar->dimen - 1)
968 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
969 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
970 tmp = fold_convert (integer_type_node, tmp);
971 extent = fold_build2_loc (input_location, MULT_EXPR,
972 integer_type_node, extent, tmp);
977 /* errmsg. */
978 if (code->expr3)
980 gfc_init_se (&argse, NULL);
981 argse.want_pointer = 1;
982 gfc_conv_expr (&argse, code->expr3);
983 gfc_add_block_to_block (&se.pre, &argse.pre);
984 errmsg = argse.expr;
985 errmsg_len = fold_convert (integer_type_node, argse.string_length);
987 else
989 errmsg = null_pointer_node;
990 errmsg_len = integer_zero_node;
993 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
995 stat2 = stat;
996 stat = gfc_create_var (integer_type_node, "stat");
999 if (op == EXEC_EVENT_POST)
1000 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1001 token, index, image_index,
1002 stat != null_pointer_node
1003 ? gfc_build_addr_expr (NULL, stat) : stat,
1004 errmsg, errmsg_len);
1005 else
1006 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1007 token, index, until_count,
1008 stat != null_pointer_node
1009 ? gfc_build_addr_expr (NULL, stat) : stat,
1010 errmsg, errmsg_len);
1011 gfc_add_expr_to_block (&se.pre, tmp);
1013 /* It guarantees memory consistency within the same segment */
1014 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1015 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1016 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1017 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1018 ASM_VOLATILE_P (tmp) = 1;
1019 gfc_add_expr_to_block (&se.pre, tmp);
1021 if (stat2 != NULL_TREE)
1022 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1024 return gfc_finish_block (&se.pre);
1027 tree
1028 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1030 gfc_se se, argse;
1031 tree tmp;
1032 tree images = NULL_TREE, stat = NULL_TREE,
1033 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1035 /* Short cut: For single images without bound checking or without STAT=,
1036 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1037 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1038 && flag_coarray != GFC_FCOARRAY_LIB)
1039 return NULL_TREE;
1041 gfc_init_se (&se, NULL);
1042 gfc_start_block (&se.pre);
1044 if (code->expr1 && code->expr1->rank == 0)
1046 gfc_init_se (&argse, NULL);
1047 gfc_conv_expr_val (&argse, code->expr1);
1048 images = argse.expr;
1051 if (code->expr2)
1053 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1054 gfc_init_se (&argse, NULL);
1055 gfc_conv_expr_val (&argse, code->expr2);
1056 stat = argse.expr;
1058 else
1059 stat = null_pointer_node;
1061 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1063 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1064 gfc_init_se (&argse, NULL);
1065 argse.want_pointer = 1;
1066 gfc_conv_expr (&argse, code->expr3);
1067 gfc_conv_string_parameter (&argse);
1068 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1069 errmsglen = argse.string_length;
1071 else if (flag_coarray == GFC_FCOARRAY_LIB)
1073 errmsg = null_pointer_node;
1074 errmsglen = build_int_cst (integer_type_node, 0);
1077 /* Check SYNC IMAGES(imageset) for valid image index.
1078 FIXME: Add a check for image-set arrays. */
1079 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1080 && code->expr1->rank == 0)
1082 tree cond;
1083 if (flag_coarray != GFC_FCOARRAY_LIB)
1084 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1085 images, build_int_cst (TREE_TYPE (images), 1));
1086 else
1088 tree cond2;
1089 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1090 2, integer_zero_node,
1091 build_int_cst (integer_type_node, -1));
1092 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1093 images, tmp);
1094 cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1095 images,
1096 build_int_cst (TREE_TYPE (images), 1));
1097 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1098 boolean_type_node, cond, cond2);
1100 gfc_trans_runtime_check (true, false, cond, &se.pre,
1101 &code->expr1->where, "Invalid image number "
1102 "%d in SYNC IMAGES",
1103 fold_convert (integer_type_node, images));
1106 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1107 image control statements SYNC IMAGES and SYNC ALL. */
1108 if (flag_coarray == GFC_FCOARRAY_LIB)
1110 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1111 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1112 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1113 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1114 ASM_VOLATILE_P (tmp) = 1;
1115 gfc_add_expr_to_block (&se.pre, tmp);
1118 if (flag_coarray != GFC_FCOARRAY_LIB)
1120 /* Set STAT to zero. */
1121 if (code->expr2)
1122 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1124 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1126 /* SYNC ALL => stat == null_pointer_node
1127 SYNC ALL(stat=s) => stat has an integer type
1129 If "stat" has the wrong integer type, use a temp variable of
1130 the right type and later cast the result back into "stat". */
1131 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1133 if (TREE_TYPE (stat) == integer_type_node)
1134 stat = gfc_build_addr_expr (NULL, stat);
1136 if(type == EXEC_SYNC_MEMORY)
1137 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1138 3, stat, errmsg, errmsglen);
1139 else
1140 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1141 3, stat, errmsg, errmsglen);
1143 gfc_add_expr_to_block (&se.pre, tmp);
1145 else
1147 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1149 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1150 3, gfc_build_addr_expr (NULL, tmp_stat),
1151 errmsg, errmsglen);
1152 gfc_add_expr_to_block (&se.pre, tmp);
1154 gfc_add_modify (&se.pre, stat,
1155 fold_convert (TREE_TYPE (stat), tmp_stat));
1158 else
1160 tree len;
1162 gcc_assert (type == EXEC_SYNC_IMAGES);
1164 if (!code->expr1)
1166 len = build_int_cst (integer_type_node, -1);
1167 images = null_pointer_node;
1169 else if (code->expr1->rank == 0)
1171 len = build_int_cst (integer_type_node, 1);
1172 images = gfc_build_addr_expr (NULL_TREE, images);
1174 else
1176 /* FIXME. */
1177 if (code->expr1->ts.kind != gfc_c_int_kind)
1178 gfc_fatal_error ("Sorry, only support for integer kind %d "
1179 "implemented for image-set at %L",
1180 gfc_c_int_kind, &code->expr1->where);
1182 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1183 images = se.expr;
1185 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1186 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1187 tmp = gfc_get_element_type (tmp);
1189 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1190 TREE_TYPE (len), len,
1191 fold_convert (TREE_TYPE (len),
1192 TYPE_SIZE_UNIT (tmp)));
1193 len = fold_convert (integer_type_node, len);
1196 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1197 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1199 If "stat" has the wrong integer type, use a temp variable of
1200 the right type and later cast the result back into "stat". */
1201 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1203 if (TREE_TYPE (stat) == integer_type_node)
1204 stat = gfc_build_addr_expr (NULL, stat);
1206 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1207 5, fold_convert (integer_type_node, len),
1208 images, stat, errmsg, errmsglen);
1209 gfc_add_expr_to_block (&se.pre, tmp);
1211 else
1213 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1215 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1216 5, fold_convert (integer_type_node, len),
1217 images, gfc_build_addr_expr (NULL, tmp_stat),
1218 errmsg, errmsglen);
1219 gfc_add_expr_to_block (&se.pre, tmp);
1221 gfc_add_modify (&se.pre, stat,
1222 fold_convert (TREE_TYPE (stat), tmp_stat));
1226 return gfc_finish_block (&se.pre);
1230 /* Generate GENERIC for the IF construct. This function also deals with
1231 the simple IF statement, because the front end translates the IF
1232 statement into an IF construct.
1234 We translate:
1236 IF (cond) THEN
1237 then_clause
1238 ELSEIF (cond2)
1239 elseif_clause
1240 ELSE
1241 else_clause
1242 ENDIF
1244 into:
1246 pre_cond_s;
1247 if (cond_s)
1249 then_clause;
1251 else
1253 pre_cond_s
1254 if (cond_s)
1256 elseif_clause
1258 else
1260 else_clause;
1264 where COND_S is the simplified version of the predicate. PRE_COND_S
1265 are the pre side-effects produced by the translation of the
1266 conditional.
1267 We need to build the chain recursively otherwise we run into
1268 problems with folding incomplete statements. */
1270 static tree
1271 gfc_trans_if_1 (gfc_code * code)
1273 gfc_se if_se;
1274 tree stmt, elsestmt;
1275 locus saved_loc;
1276 location_t loc;
1278 /* Check for an unconditional ELSE clause. */
1279 if (!code->expr1)
1280 return gfc_trans_code (code->next);
1282 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1283 gfc_init_se (&if_se, NULL);
1284 gfc_start_block (&if_se.pre);
1286 /* Calculate the IF condition expression. */
1287 if (code->expr1->where.lb)
1289 gfc_save_backend_locus (&saved_loc);
1290 gfc_set_backend_locus (&code->expr1->where);
1293 gfc_conv_expr_val (&if_se, code->expr1);
1295 if (code->expr1->where.lb)
1296 gfc_restore_backend_locus (&saved_loc);
1298 /* Translate the THEN clause. */
1299 stmt = gfc_trans_code (code->next);
1301 /* Translate the ELSE clause. */
1302 if (code->block)
1303 elsestmt = gfc_trans_if_1 (code->block);
1304 else
1305 elsestmt = build_empty_stmt (input_location);
1307 /* Build the condition expression and add it to the condition block. */
1308 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1309 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1310 elsestmt);
1312 gfc_add_expr_to_block (&if_se.pre, stmt);
1314 /* Finish off this statement. */
1315 return gfc_finish_block (&if_se.pre);
1318 tree
1319 gfc_trans_if (gfc_code * code)
1321 stmtblock_t body;
1322 tree exit_label;
1324 /* Create exit label so it is available for trans'ing the body code. */
1325 exit_label = gfc_build_label_decl (NULL_TREE);
1326 code->exit_label = exit_label;
1328 /* Translate the actual code in code->block. */
1329 gfc_init_block (&body);
1330 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1332 /* Add exit label. */
1333 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1335 return gfc_finish_block (&body);
1339 /* Translate an arithmetic IF expression.
1341 IF (cond) label1, label2, label3 translates to
1343 if (cond <= 0)
1345 if (cond < 0)
1346 goto label1;
1347 else // cond == 0
1348 goto label2;
1350 else // cond > 0
1351 goto label3;
1353 An optimized version can be generated in case of equal labels.
1354 E.g., if label1 is equal to label2, we can translate it to
1356 if (cond <= 0)
1357 goto label1;
1358 else
1359 goto label3;
1362 tree
1363 gfc_trans_arithmetic_if (gfc_code * code)
1365 gfc_se se;
1366 tree tmp;
1367 tree branch1;
1368 tree branch2;
1369 tree zero;
1371 /* Start a new block. */
1372 gfc_init_se (&se, NULL);
1373 gfc_start_block (&se.pre);
1375 /* Pre-evaluate COND. */
1376 gfc_conv_expr_val (&se, code->expr1);
1377 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1379 /* Build something to compare with. */
1380 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1382 if (code->label1->value != code->label2->value)
1384 /* If (cond < 0) take branch1 else take branch2.
1385 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1386 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1387 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1389 if (code->label1->value != code->label3->value)
1390 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1391 se.expr, zero);
1392 else
1393 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1394 se.expr, zero);
1396 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1397 tmp, branch1, branch2);
1399 else
1400 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1402 if (code->label1->value != code->label3->value
1403 && code->label2->value != code->label3->value)
1405 /* if (cond <= 0) take branch1 else take branch2. */
1406 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1407 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1408 se.expr, zero);
1409 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1410 tmp, branch1, branch2);
1413 /* Append the COND_EXPR to the evaluation of COND, and return. */
1414 gfc_add_expr_to_block (&se.pre, branch1);
1415 return gfc_finish_block (&se.pre);
1419 /* Translate a CRITICAL block. */
1420 tree
1421 gfc_trans_critical (gfc_code *code)
1423 stmtblock_t block;
1424 tree tmp, token = NULL_TREE;
1426 gfc_start_block (&block);
1428 if (flag_coarray == GFC_FCOARRAY_LIB)
1430 token = gfc_get_symbol_decl (code->resolved_sym);
1431 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1432 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1433 token, integer_zero_node, integer_one_node,
1434 null_pointer_node, null_pointer_node,
1435 null_pointer_node, integer_zero_node);
1436 gfc_add_expr_to_block (&block, tmp);
1438 /* It guarantees memory consistency within the same segment */
1439 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1440 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1441 gfc_build_string_const (1, ""),
1442 NULL_TREE, NULL_TREE,
1443 tree_cons (NULL_TREE, tmp, NULL_TREE),
1444 NULL_TREE);
1445 ASM_VOLATILE_P (tmp) = 1;
1447 gfc_add_expr_to_block (&block, tmp);
1450 tmp = gfc_trans_code (code->block->next);
1451 gfc_add_expr_to_block (&block, tmp);
1453 if (flag_coarray == GFC_FCOARRAY_LIB)
1455 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1456 token, integer_zero_node, integer_one_node,
1457 null_pointer_node, null_pointer_node,
1458 integer_zero_node);
1459 gfc_add_expr_to_block (&block, tmp);
1461 /* It guarantees memory consistency within the same segment */
1462 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1463 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1464 gfc_build_string_const (1, ""),
1465 NULL_TREE, NULL_TREE,
1466 tree_cons (NULL_TREE, tmp, NULL_TREE),
1467 NULL_TREE);
1468 ASM_VOLATILE_P (tmp) = 1;
1470 gfc_add_expr_to_block (&block, tmp);
1473 return gfc_finish_block (&block);
1477 /* Return true, when the class has a _len component. */
1479 static bool
1480 class_has_len_component (gfc_symbol *sym)
1482 gfc_component *comp = sym->ts.u.derived->components;
1483 while (comp)
1485 if (strcmp (comp->name, "_len") == 0)
1486 return true;
1487 comp = comp->next;
1489 return false;
1493 /* Do proper initialization for ASSOCIATE names. */
1495 static void
1496 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1498 gfc_expr *e;
1499 tree tmp;
1500 bool class_target;
1501 bool unlimited;
1502 tree desc;
1503 tree offset;
1504 tree dim;
1505 int n;
1506 tree charlen;
1507 bool need_len_assign;
1509 gcc_assert (sym->assoc);
1510 e = sym->assoc->target;
1512 class_target = (e->expr_type == EXPR_VARIABLE)
1513 && (gfc_is_class_scalar_expr (e)
1514 || gfc_is_class_array_ref (e, NULL));
1516 unlimited = UNLIMITED_POLY (e);
1518 /* Assignments to the string length need to be generated, when
1519 ( sym is a char array or
1520 sym has a _len component)
1521 and the associated expression is unlimited polymorphic, which is
1522 not (yet) correctly in 'unlimited', because for an already associated
1523 BT_DERIVED the u-poly flag is not set, i.e.,
1524 __tmp_CHARACTER_0_1 => w => arg
1525 ^ generated temp ^ from code, the w does not have the u-poly
1526 flag set, where UNLIMITED_POLY(e) expects it. */
1527 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1528 && e->ts.u.derived->attr.unlimited_polymorphic))
1529 && (sym->ts.type == BT_CHARACTER
1530 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1531 && class_has_len_component (sym))));
1532 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1533 to array temporary) for arrays with either unknown shape or if associating
1534 to a variable. */
1535 if (sym->attr.dimension && !class_target
1536 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1538 gfc_se se;
1539 tree desc;
1540 bool cst_array_ctor;
1542 desc = sym->backend_decl;
1543 cst_array_ctor = e->expr_type == EXPR_ARRAY
1544 && gfc_constant_array_constructor_p (e->value.constructor);
1546 /* If association is to an expression, evaluate it and create temporary.
1547 Otherwise, get descriptor of target for pointer assignment. */
1548 gfc_init_se (&se, NULL);
1549 if (sym->assoc->variable || cst_array_ctor)
1551 se.direct_byref = 1;
1552 se.use_offset = 1;
1553 se.expr = desc;
1556 gfc_conv_expr_descriptor (&se, e);
1558 /* If we didn't already do the pointer assignment, set associate-name
1559 descriptor to the one generated for the temporary. */
1560 if (!sym->assoc->variable && !cst_array_ctor)
1562 int dim;
1564 gfc_add_modify (&se.pre, desc, se.expr);
1566 /* The generated descriptor has lower bound zero (as array
1567 temporary), shift bounds so we get lower bounds of 1. */
1568 for (dim = 0; dim < e->rank; ++dim)
1569 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1570 dim, gfc_index_one_node);
1573 /* If this is a subreference array pointer associate name use the
1574 associate variable element size for the value of 'span'. */
1575 if (sym->attr.subref_array_pointer)
1577 gcc_assert (e->expr_type == EXPR_VARIABLE);
1578 tmp = e->symtree->n.sym->ts.type == BT_CLASS
1579 ? gfc_class_data_get (e->symtree->n.sym->backend_decl)
1580 : e->symtree->n.sym->backend_decl;
1581 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1582 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1583 gfc_add_modify (&se.pre, GFC_DECL_SPAN(desc), tmp);
1586 /* Done, register stuff as init / cleanup code. */
1587 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1588 gfc_finish_block (&se.post));
1591 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1592 arrays to be assigned directly. */
1593 else if (class_target && sym->attr.dimension
1594 && (sym->ts.type == BT_DERIVED || unlimited))
1596 gfc_se se;
1598 gfc_init_se (&se, NULL);
1599 se.descriptor_only = 1;
1600 /* In a select type the (temporary) associate variable shall point to
1601 a standard fortran array (lower bound == 1), but conv_expr ()
1602 just maps to the input array in the class object, whose lbound may
1603 be arbitrary. conv_expr_descriptor solves this by inserting a
1604 temporary array descriptor. */
1605 gfc_conv_expr_descriptor (&se, e);
1607 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1608 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1609 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1611 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1613 if (INDIRECT_REF_P (se.expr))
1614 tmp = TREE_OPERAND (se.expr, 0);
1615 else
1616 tmp = se.expr;
1618 gfc_add_modify (&se.pre, sym->backend_decl,
1619 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1621 else
1622 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1624 if (unlimited)
1626 /* Recover the dtype, which has been overwritten by the
1627 assignment from an unlimited polymorphic object. */
1628 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1629 gfc_add_modify (&se.pre, tmp,
1630 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1633 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1634 gfc_finish_block (&se.post));
1637 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1638 else if (gfc_is_associate_pointer (sym))
1640 gfc_se se;
1642 gcc_assert (!sym->attr.dimension);
1644 gfc_init_se (&se, NULL);
1646 /* Class associate-names come this way because they are
1647 unconditionally associate pointers and the symbol is scalar. */
1648 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1650 tree target_expr;
1651 /* For a class array we need a descriptor for the selector. */
1652 gfc_conv_expr_descriptor (&se, e);
1653 /* Needed to get/set the _len component below. */
1654 target_expr = se.expr;
1656 /* Obtain a temporary class container for the result. */
1657 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1658 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1660 /* Set the offset. */
1661 desc = gfc_class_data_get (se.expr);
1662 offset = gfc_index_zero_node;
1663 for (n = 0; n < e->rank; n++)
1665 dim = gfc_rank_cst[n];
1666 tmp = fold_build2_loc (input_location, MULT_EXPR,
1667 gfc_array_index_type,
1668 gfc_conv_descriptor_stride_get (desc, dim),
1669 gfc_conv_descriptor_lbound_get (desc, dim));
1670 offset = fold_build2_loc (input_location, MINUS_EXPR,
1671 gfc_array_index_type,
1672 offset, tmp);
1674 if (need_len_assign)
1676 if (e->symtree
1677 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1678 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1679 /* Use the original class descriptor stored in the saved
1680 descriptor to get the target_expr. */
1681 target_expr =
1682 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1683 else
1684 /* Strip the _data component from the target_expr. */
1685 target_expr = TREE_OPERAND (target_expr, 0);
1686 /* Add a reference to the _len comp to the target expr. */
1687 tmp = gfc_class_len_get (target_expr);
1688 /* Get the component-ref for the temp structure's _len comp. */
1689 charlen = gfc_class_len_get (se.expr);
1690 /* Add the assign to the beginning of the block... */
1691 gfc_add_modify (&se.pre, charlen,
1692 fold_convert (TREE_TYPE (charlen), tmp));
1693 /* and the oposite way at the end of the block, to hand changes
1694 on the string length back. */
1695 gfc_add_modify (&se.post, tmp,
1696 fold_convert (TREE_TYPE (tmp), charlen));
1697 /* Length assignment done, prevent adding it again below. */
1698 need_len_assign = false;
1700 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1702 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1703 && CLASS_DATA (e)->attr.dimension)
1705 /* This is bound to be a class array element. */
1706 gfc_conv_expr_reference (&se, e);
1707 /* Get the _vptr component of the class object. */
1708 tmp = gfc_get_vptr_from_expr (se.expr);
1709 /* Obtain a temporary class container for the result. */
1710 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1711 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1713 else
1715 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1716 which has the string length included. For CHARACTERS it is still
1717 needed and will be done at the end of this routine. */
1718 gfc_conv_expr (&se, e);
1719 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1722 tmp = TREE_TYPE (sym->backend_decl);
1723 tmp = gfc_build_addr_expr (tmp, se.expr);
1724 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1726 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1727 gfc_finish_block (&se.post));
1730 /* Do a simple assignment. This is for scalar expressions, where we
1731 can simply use expression assignment. */
1732 else
1734 gfc_expr *lhs;
1736 lhs = gfc_lval_expr_from_sym (sym);
1737 tmp = gfc_trans_assignment (lhs, e, false, true);
1738 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1741 /* Set the stringlength, when needed. */
1742 if (need_len_assign)
1744 gfc_se se;
1745 gfc_init_se (&se, NULL);
1746 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1748 /* What about deferred strings? */
1749 gcc_assert (!e->symtree->n.sym->ts.deferred);
1750 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1752 else
1753 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1754 gfc_get_symbol_decl (sym);
1755 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1756 : gfc_class_len_get (sym->backend_decl);
1757 /* Prevent adding a noop len= len. */
1758 if (tmp != charlen)
1760 gfc_add_modify (&se.pre, charlen,
1761 fold_convert (TREE_TYPE (charlen), tmp));
1762 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1763 gfc_finish_block (&se.post));
1769 /* Translate a BLOCK construct. This is basically what we would do for a
1770 procedure body. */
1772 tree
1773 gfc_trans_block_construct (gfc_code* code)
1775 gfc_namespace* ns;
1776 gfc_symbol* sym;
1777 gfc_wrapped_block block;
1778 tree exit_label;
1779 stmtblock_t body;
1780 gfc_association_list *ass;
1782 ns = code->ext.block.ns;
1783 gcc_assert (ns);
1784 sym = ns->proc_name;
1785 gcc_assert (sym);
1787 /* Process local variables. */
1788 gcc_assert (!sym->tlink);
1789 sym->tlink = sym;
1790 gfc_process_block_locals (ns);
1792 /* Generate code including exit-label. */
1793 gfc_init_block (&body);
1794 exit_label = gfc_build_label_decl (NULL_TREE);
1795 code->exit_label = exit_label;
1797 finish_oacc_declare (ns, sym, true);
1799 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1800 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1802 /* Finish everything. */
1803 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1804 gfc_trans_deferred_vars (sym, &block);
1805 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1806 trans_associate_var (ass->st->n.sym, &block);
1808 return gfc_finish_wrapped_block (&block);
1812 /* Translate the simple DO construct. This is where the loop variable has
1813 integer type and step +-1. We can't use this in the general case
1814 because integer overflow and floating point errors could give incorrect
1815 results.
1816 We translate a do loop from:
1818 DO dovar = from, to, step
1819 body
1820 END DO
1824 [Evaluate loop bounds and step]
1825 dovar = from;
1826 if ((step > 0) ? (dovar <= to) : (dovar => to))
1828 for (;;)
1830 body;
1831 cycle_label:
1832 cond = (dovar == to);
1833 dovar += step;
1834 if (cond) goto end_label;
1837 end_label:
1839 This helps the optimizers by avoiding the extra induction variable
1840 used in the general case. */
1842 static tree
1843 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1844 tree from, tree to, tree step, tree exit_cond)
1846 stmtblock_t body;
1847 tree type;
1848 tree cond;
1849 tree tmp;
1850 tree saved_dovar = NULL;
1851 tree cycle_label;
1852 tree exit_label;
1853 location_t loc;
1855 type = TREE_TYPE (dovar);
1857 loc = code->ext.iterator->start->where.lb->location;
1859 /* Initialize the DO variable: dovar = from. */
1860 gfc_add_modify_loc (loc, pblock, dovar,
1861 fold_convert (TREE_TYPE(dovar), from));
1863 /* Save value for do-tinkering checking. */
1864 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1866 saved_dovar = gfc_create_var (type, ".saved_dovar");
1867 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1870 /* Cycle and exit statements are implemented with gotos. */
1871 cycle_label = gfc_build_label_decl (NULL_TREE);
1872 exit_label = gfc_build_label_decl (NULL_TREE);
1874 /* Put the labels where they can be found later. See gfc_trans_do(). */
1875 code->cycle_label = cycle_label;
1876 code->exit_label = exit_label;
1878 /* Loop body. */
1879 gfc_start_block (&body);
1881 /* Main loop body. */
1882 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1883 gfc_add_expr_to_block (&body, tmp);
1885 /* Label for cycle statements (if needed). */
1886 if (TREE_USED (cycle_label))
1888 tmp = build1_v (LABEL_EXPR, cycle_label);
1889 gfc_add_expr_to_block (&body, tmp);
1892 /* Check whether someone has modified the loop variable. */
1893 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1895 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1896 dovar, saved_dovar);
1897 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1898 "Loop variable has been modified");
1901 /* Exit the loop if there is an I/O result condition or error. */
1902 if (exit_cond)
1904 tmp = build1_v (GOTO_EXPR, exit_label);
1905 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1906 exit_cond, tmp,
1907 build_empty_stmt (loc));
1908 gfc_add_expr_to_block (&body, tmp);
1911 /* Evaluate the loop condition. */
1912 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, dovar,
1913 to);
1914 cond = gfc_evaluate_now_loc (loc, cond, &body);
1916 /* Increment the loop variable. */
1917 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1918 gfc_add_modify_loc (loc, &body, dovar, tmp);
1920 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1921 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1923 /* The loop exit. */
1924 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1925 TREE_USED (exit_label) = 1;
1926 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1927 cond, tmp, build_empty_stmt (loc));
1928 gfc_add_expr_to_block (&body, tmp);
1930 /* Finish the loop body. */
1931 tmp = gfc_finish_block (&body);
1932 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1934 /* Only execute the loop if the number of iterations is positive. */
1935 if (tree_int_cst_sgn (step) > 0)
1936 cond = fold_build2_loc (loc, LE_EXPR, boolean_type_node, dovar,
1937 to);
1938 else
1939 cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node, dovar,
1940 to);
1941 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, tmp,
1942 build_empty_stmt (loc));
1943 gfc_add_expr_to_block (pblock, tmp);
1945 /* Add the exit label. */
1946 tmp = build1_v (LABEL_EXPR, exit_label);
1947 gfc_add_expr_to_block (pblock, tmp);
1949 return gfc_finish_block (pblock);
1952 /* Translate the DO construct. This obviously is one of the most
1953 important ones to get right with any compiler, but especially
1954 so for Fortran.
1956 We special case some loop forms as described in gfc_trans_simple_do.
1957 For other cases we implement them with a separate loop count,
1958 as described in the standard.
1960 We translate a do loop from:
1962 DO dovar = from, to, step
1963 body
1964 END DO
1968 [evaluate loop bounds and step]
1969 empty = (step > 0 ? to < from : to > from);
1970 countm1 = (to - from) / step;
1971 dovar = from;
1972 if (empty) goto exit_label;
1973 for (;;)
1975 body;
1976 cycle_label:
1977 dovar += step
1978 countm1t = countm1;
1979 countm1--;
1980 if (countm1t == 0) goto exit_label;
1982 exit_label:
1984 countm1 is an unsigned integer. It is equal to the loop count minus one,
1985 because the loop count itself can overflow. */
1987 tree
1988 gfc_trans_do (gfc_code * code, tree exit_cond)
1990 gfc_se se;
1991 tree dovar;
1992 tree saved_dovar = NULL;
1993 tree from;
1994 tree to;
1995 tree step;
1996 tree countm1;
1997 tree type;
1998 tree utype;
1999 tree cond;
2000 tree cycle_label;
2001 tree exit_label;
2002 tree tmp;
2003 stmtblock_t block;
2004 stmtblock_t body;
2005 location_t loc;
2007 gfc_start_block (&block);
2009 loc = code->ext.iterator->start->where.lb->location;
2011 /* Evaluate all the expressions in the iterator. */
2012 gfc_init_se (&se, NULL);
2013 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2014 gfc_add_block_to_block (&block, &se.pre);
2015 dovar = se.expr;
2016 type = TREE_TYPE (dovar);
2018 gfc_init_se (&se, NULL);
2019 gfc_conv_expr_val (&se, code->ext.iterator->start);
2020 gfc_add_block_to_block (&block, &se.pre);
2021 from = gfc_evaluate_now (se.expr, &block);
2023 gfc_init_se (&se, NULL);
2024 gfc_conv_expr_val (&se, code->ext.iterator->end);
2025 gfc_add_block_to_block (&block, &se.pre);
2026 to = gfc_evaluate_now (se.expr, &block);
2028 gfc_init_se (&se, NULL);
2029 gfc_conv_expr_val (&se, code->ext.iterator->step);
2030 gfc_add_block_to_block (&block, &se.pre);
2031 step = gfc_evaluate_now (se.expr, &block);
2033 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2035 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
2036 build_zero_cst (type));
2037 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2038 "DO step value is zero");
2041 /* Special case simple loops. */
2042 if (TREE_CODE (type) == INTEGER_TYPE
2043 && (integer_onep (step)
2044 || tree_int_cst_equal (step, integer_minus_one_node)))
2045 return gfc_trans_simple_do (code, &block, dovar, from, to, step, exit_cond);
2048 if (TREE_CODE (type) == INTEGER_TYPE)
2049 utype = unsigned_type_for (type);
2050 else
2051 utype = unsigned_type_for (gfc_array_index_type);
2052 countm1 = gfc_create_var (utype, "countm1");
2054 /* Cycle and exit statements are implemented with gotos. */
2055 cycle_label = gfc_build_label_decl (NULL_TREE);
2056 exit_label = gfc_build_label_decl (NULL_TREE);
2057 TREE_USED (exit_label) = 1;
2059 /* Put these labels where they can be found later. */
2060 code->cycle_label = cycle_label;
2061 code->exit_label = exit_label;
2063 /* Initialize the DO variable: dovar = from. */
2064 gfc_add_modify (&block, dovar, from);
2066 /* Save value for do-tinkering checking. */
2067 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2069 saved_dovar = gfc_create_var (type, ".saved_dovar");
2070 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2073 /* Initialize loop count and jump to exit label if the loop is empty.
2074 This code is executed before we enter the loop body. We generate:
2075 if (step > 0)
2077 countm1 = (to - from) / step;
2078 if (to < from)
2079 goto exit_label;
2081 else
2083 countm1 = (from - to) / -step;
2084 if (to > from)
2085 goto exit_label;
2089 if (TREE_CODE (type) == INTEGER_TYPE)
2091 tree pos, neg, tou, fromu, stepu, tmp2;
2093 /* The distance from FROM to TO cannot always be represented in a signed
2094 type, thus use unsigned arithmetic, also to avoid any undefined
2095 overflow issues. */
2096 tou = fold_convert (utype, to);
2097 fromu = fold_convert (utype, from);
2098 stepu = fold_convert (utype, step);
2100 /* For a positive step, when to < from, exit, otherwise compute
2101 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2102 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
2103 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2104 fold_build2_loc (loc, MINUS_EXPR, utype,
2105 tou, fromu),
2106 stepu);
2107 pos = build2 (COMPOUND_EXPR, void_type_node,
2108 fold_build2 (MODIFY_EXPR, void_type_node,
2109 countm1, tmp2),
2110 build3_loc (loc, COND_EXPR, void_type_node, tmp,
2111 build1_loc (loc, GOTO_EXPR, void_type_node,
2112 exit_label), NULL_TREE));
2114 /* For a negative step, when to > from, exit, otherwise compute
2115 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2116 tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, to, from);
2117 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2118 fold_build2_loc (loc, MINUS_EXPR, utype,
2119 fromu, tou),
2120 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2121 neg = build2 (COMPOUND_EXPR, void_type_node,
2122 fold_build2 (MODIFY_EXPR, void_type_node,
2123 countm1, tmp2),
2124 build3_loc (loc, COND_EXPR, void_type_node, tmp,
2125 build1_loc (loc, GOTO_EXPR, void_type_node,
2126 exit_label), NULL_TREE));
2128 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
2129 build_int_cst (TREE_TYPE (step), 0));
2130 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2132 gfc_add_expr_to_block (&block, tmp);
2134 else
2136 tree pos_step;
2138 /* TODO: We could use the same width as the real type.
2139 This would probably cause more problems that it solves
2140 when we implement "long double" types. */
2142 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2143 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2144 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2145 gfc_add_modify (&block, countm1, tmp);
2147 /* We need a special check for empty loops:
2148 empty = (step > 0 ? to < from : to > from); */
2149 pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
2150 build_zero_cst (type));
2151 tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
2152 fold_build2_loc (loc, LT_EXPR,
2153 boolean_type_node, to, from),
2154 fold_build2_loc (loc, GT_EXPR,
2155 boolean_type_node, to, from));
2156 /* If the loop is empty, go directly to the exit label. */
2157 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2158 build1_v (GOTO_EXPR, exit_label),
2159 build_empty_stmt (input_location));
2160 gfc_add_expr_to_block (&block, tmp);
2163 /* Loop body. */
2164 gfc_start_block (&body);
2166 /* Main loop body. */
2167 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2168 gfc_add_expr_to_block (&body, tmp);
2170 /* Label for cycle statements (if needed). */
2171 if (TREE_USED (cycle_label))
2173 tmp = build1_v (LABEL_EXPR, cycle_label);
2174 gfc_add_expr_to_block (&body, tmp);
2177 /* Check whether someone has modified the loop variable. */
2178 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2180 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
2181 saved_dovar);
2182 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2183 "Loop variable has been modified");
2186 /* Exit the loop if there is an I/O result condition or error. */
2187 if (exit_cond)
2189 tmp = build1_v (GOTO_EXPR, exit_label);
2190 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2191 exit_cond, tmp,
2192 build_empty_stmt (input_location));
2193 gfc_add_expr_to_block (&body, tmp);
2196 /* Increment the loop variable. */
2197 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2198 gfc_add_modify_loc (loc, &body, dovar, tmp);
2200 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2201 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2203 /* Initialize countm1t. */
2204 tree countm1t = gfc_create_var (utype, "countm1t");
2205 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2207 /* Decrement the loop count. */
2208 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2209 build_int_cst (utype, 1));
2210 gfc_add_modify_loc (loc, &body, countm1, tmp);
2212 /* End with the loop condition. Loop until countm1t == 0. */
2213 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, countm1t,
2214 build_int_cst (utype, 0));
2215 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2216 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2217 cond, tmp, build_empty_stmt (loc));
2218 gfc_add_expr_to_block (&body, tmp);
2220 /* End of loop body. */
2221 tmp = gfc_finish_block (&body);
2223 /* The for loop itself. */
2224 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2225 gfc_add_expr_to_block (&block, tmp);
2227 /* Add the exit label. */
2228 tmp = build1_v (LABEL_EXPR, exit_label);
2229 gfc_add_expr_to_block (&block, tmp);
2231 return gfc_finish_block (&block);
2235 /* Translate the DO WHILE construct.
2237 We translate
2239 DO WHILE (cond)
2240 body
2241 END DO
2245 for ( ; ; )
2247 pre_cond;
2248 if (! cond) goto exit_label;
2249 body;
2250 cycle_label:
2252 exit_label:
2254 Because the evaluation of the exit condition `cond' may have side
2255 effects, we can't do much for empty loop bodies. The backend optimizers
2256 should be smart enough to eliminate any dead loops. */
2258 tree
2259 gfc_trans_do_while (gfc_code * code)
2261 gfc_se cond;
2262 tree tmp;
2263 tree cycle_label;
2264 tree exit_label;
2265 stmtblock_t block;
2267 /* Everything we build here is part of the loop body. */
2268 gfc_start_block (&block);
2270 /* Cycle and exit statements are implemented with gotos. */
2271 cycle_label = gfc_build_label_decl (NULL_TREE);
2272 exit_label = gfc_build_label_decl (NULL_TREE);
2274 /* Put the labels where they can be found later. See gfc_trans_do(). */
2275 code->cycle_label = cycle_label;
2276 code->exit_label = exit_label;
2278 /* Create a GIMPLE version of the exit condition. */
2279 gfc_init_se (&cond, NULL);
2280 gfc_conv_expr_val (&cond, code->expr1);
2281 gfc_add_block_to_block (&block, &cond.pre);
2282 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2283 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2285 /* Build "IF (! cond) GOTO exit_label". */
2286 tmp = build1_v (GOTO_EXPR, exit_label);
2287 TREE_USED (exit_label) = 1;
2288 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2289 void_type_node, cond.expr, tmp,
2290 build_empty_stmt (code->expr1->where.lb->location));
2291 gfc_add_expr_to_block (&block, tmp);
2293 /* The main body of the loop. */
2294 tmp = gfc_trans_code (code->block->next);
2295 gfc_add_expr_to_block (&block, tmp);
2297 /* Label for cycle statements (if needed). */
2298 if (TREE_USED (cycle_label))
2300 tmp = build1_v (LABEL_EXPR, cycle_label);
2301 gfc_add_expr_to_block (&block, tmp);
2304 /* End of loop body. */
2305 tmp = gfc_finish_block (&block);
2307 gfc_init_block (&block);
2308 /* Build the loop. */
2309 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2310 void_type_node, tmp);
2311 gfc_add_expr_to_block (&block, tmp);
2313 /* Add the exit label. */
2314 tmp = build1_v (LABEL_EXPR, exit_label);
2315 gfc_add_expr_to_block (&block, tmp);
2317 return gfc_finish_block (&block);
2321 /* Translate the SELECT CASE construct for INTEGER case expressions,
2322 without killing all potential optimizations. The problem is that
2323 Fortran allows unbounded cases, but the back-end does not, so we
2324 need to intercept those before we enter the equivalent SWITCH_EXPR
2325 we can build.
2327 For example, we translate this,
2329 SELECT CASE (expr)
2330 CASE (:100,101,105:115)
2331 block_1
2332 CASE (190:199,200:)
2333 block_2
2334 CASE (300)
2335 block_3
2336 CASE DEFAULT
2337 block_4
2338 END SELECT
2340 to the GENERIC equivalent,
2342 switch (expr)
2344 case (minimum value for typeof(expr) ... 100:
2345 case 101:
2346 case 105 ... 114:
2347 block1:
2348 goto end_label;
2350 case 200 ... (maximum value for typeof(expr):
2351 case 190 ... 199:
2352 block2;
2353 goto end_label;
2355 case 300:
2356 block_3;
2357 goto end_label;
2359 default:
2360 block_4;
2361 goto end_label;
2364 end_label: */
2366 static tree
2367 gfc_trans_integer_select (gfc_code * code)
2369 gfc_code *c;
2370 gfc_case *cp;
2371 tree end_label;
2372 tree tmp;
2373 gfc_se se;
2374 stmtblock_t block;
2375 stmtblock_t body;
2377 gfc_start_block (&block);
2379 /* Calculate the switch expression. */
2380 gfc_init_se (&se, NULL);
2381 gfc_conv_expr_val (&se, code->expr1);
2382 gfc_add_block_to_block (&block, &se.pre);
2384 end_label = gfc_build_label_decl (NULL_TREE);
2386 gfc_init_block (&body);
2388 for (c = code->block; c; c = c->block)
2390 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2392 tree low, high;
2393 tree label;
2395 /* Assume it's the default case. */
2396 low = high = NULL_TREE;
2398 if (cp->low)
2400 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2401 cp->low->ts.kind);
2403 /* If there's only a lower bound, set the high bound to the
2404 maximum value of the case expression. */
2405 if (!cp->high)
2406 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2409 if (cp->high)
2411 /* Three cases are possible here:
2413 1) There is no lower bound, e.g. CASE (:N).
2414 2) There is a lower bound .NE. high bound, that is
2415 a case range, e.g. CASE (N:M) where M>N (we make
2416 sure that M>N during type resolution).
2417 3) There is a lower bound, and it has the same value
2418 as the high bound, e.g. CASE (N:N). This is our
2419 internal representation of CASE(N).
2421 In the first and second case, we need to set a value for
2422 high. In the third case, we don't because the GCC middle
2423 end represents a single case value by just letting high be
2424 a NULL_TREE. We can't do that because we need to be able
2425 to represent unbounded cases. */
2427 if (!cp->low
2428 || (cp->low
2429 && mpz_cmp (cp->low->value.integer,
2430 cp->high->value.integer) != 0))
2431 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2432 cp->high->ts.kind);
2434 /* Unbounded case. */
2435 if (!cp->low)
2436 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2439 /* Build a label. */
2440 label = gfc_build_label_decl (NULL_TREE);
2442 /* Add this case label.
2443 Add parameter 'label', make it match GCC backend. */
2444 tmp = build_case_label (low, high, label);
2445 gfc_add_expr_to_block (&body, tmp);
2448 /* Add the statements for this case. */
2449 tmp = gfc_trans_code (c->next);
2450 gfc_add_expr_to_block (&body, tmp);
2452 /* Break to the end of the construct. */
2453 tmp = build1_v (GOTO_EXPR, end_label);
2454 gfc_add_expr_to_block (&body, tmp);
2457 tmp = gfc_finish_block (&body);
2458 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2459 se.expr, tmp, NULL_TREE);
2460 gfc_add_expr_to_block (&block, tmp);
2462 tmp = build1_v (LABEL_EXPR, end_label);
2463 gfc_add_expr_to_block (&block, tmp);
2465 return gfc_finish_block (&block);
2469 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2471 There are only two cases possible here, even though the standard
2472 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2473 .FALSE., and DEFAULT.
2475 We never generate more than two blocks here. Instead, we always
2476 try to eliminate the DEFAULT case. This way, we can translate this
2477 kind of SELECT construct to a simple
2479 if {} else {};
2481 expression in GENERIC. */
2483 static tree
2484 gfc_trans_logical_select (gfc_code * code)
2486 gfc_code *c;
2487 gfc_code *t, *f, *d;
2488 gfc_case *cp;
2489 gfc_se se;
2490 stmtblock_t block;
2492 /* Assume we don't have any cases at all. */
2493 t = f = d = NULL;
2495 /* Now see which ones we actually do have. We can have at most two
2496 cases in a single case list: one for .TRUE. and one for .FALSE.
2497 The default case is always separate. If the cases for .TRUE. and
2498 .FALSE. are in the same case list, the block for that case list
2499 always executed, and we don't generate code a COND_EXPR. */
2500 for (c = code->block; c; c = c->block)
2502 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2504 if (cp->low)
2506 if (cp->low->value.logical == 0) /* .FALSE. */
2507 f = c;
2508 else /* if (cp->value.logical != 0), thus .TRUE. */
2509 t = c;
2511 else
2512 d = c;
2516 /* Start a new block. */
2517 gfc_start_block (&block);
2519 /* Calculate the switch expression. We always need to do this
2520 because it may have side effects. */
2521 gfc_init_se (&se, NULL);
2522 gfc_conv_expr_val (&se, code->expr1);
2523 gfc_add_block_to_block (&block, &se.pre);
2525 if (t == f && t != NULL)
2527 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2528 translate the code for these cases, append it to the current
2529 block. */
2530 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2532 else
2534 tree true_tree, false_tree, stmt;
2536 true_tree = build_empty_stmt (input_location);
2537 false_tree = build_empty_stmt (input_location);
2539 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2540 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2541 make the missing case the default case. */
2542 if (t != NULL && f != NULL)
2543 d = NULL;
2544 else if (d != NULL)
2546 if (t == NULL)
2547 t = d;
2548 else
2549 f = d;
2552 /* Translate the code for each of these blocks, and append it to
2553 the current block. */
2554 if (t != NULL)
2555 true_tree = gfc_trans_code (t->next);
2557 if (f != NULL)
2558 false_tree = gfc_trans_code (f->next);
2560 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2561 se.expr, true_tree, false_tree);
2562 gfc_add_expr_to_block (&block, stmt);
2565 return gfc_finish_block (&block);
2569 /* The jump table types are stored in static variables to avoid
2570 constructing them from scratch every single time. */
2571 static GTY(()) tree select_struct[2];
2573 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2574 Instead of generating compares and jumps, it is far simpler to
2575 generate a data structure describing the cases in order and call a
2576 library subroutine that locates the right case.
2577 This is particularly true because this is the only case where we
2578 might have to dispose of a temporary.
2579 The library subroutine returns a pointer to jump to or NULL if no
2580 branches are to be taken. */
2582 static tree
2583 gfc_trans_character_select (gfc_code *code)
2585 tree init, end_label, tmp, type, case_num, label, fndecl;
2586 stmtblock_t block, body;
2587 gfc_case *cp, *d;
2588 gfc_code *c;
2589 gfc_se se, expr1se;
2590 int n, k;
2591 vec<constructor_elt, va_gc> *inits = NULL;
2593 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2595 /* The jump table types are stored in static variables to avoid
2596 constructing them from scratch every single time. */
2597 static tree ss_string1[2], ss_string1_len[2];
2598 static tree ss_string2[2], ss_string2_len[2];
2599 static tree ss_target[2];
2601 cp = code->block->ext.block.case_list;
2602 while (cp->left != NULL)
2603 cp = cp->left;
2605 /* Generate the body */
2606 gfc_start_block (&block);
2607 gfc_init_se (&expr1se, NULL);
2608 gfc_conv_expr_reference (&expr1se, code->expr1);
2610 gfc_add_block_to_block (&block, &expr1se.pre);
2612 end_label = gfc_build_label_decl (NULL_TREE);
2614 gfc_init_block (&body);
2616 /* Attempt to optimize length 1 selects. */
2617 if (integer_onep (expr1se.string_length))
2619 for (d = cp; d; d = d->right)
2621 int i;
2622 if (d->low)
2624 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2625 && d->low->ts.type == BT_CHARACTER);
2626 if (d->low->value.character.length > 1)
2628 for (i = 1; i < d->low->value.character.length; i++)
2629 if (d->low->value.character.string[i] != ' ')
2630 break;
2631 if (i != d->low->value.character.length)
2633 if (optimize && d->high && i == 1)
2635 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2636 && d->high->ts.type == BT_CHARACTER);
2637 if (d->high->value.character.length > 1
2638 && (d->low->value.character.string[0]
2639 == d->high->value.character.string[0])
2640 && d->high->value.character.string[1] != ' '
2641 && ((d->low->value.character.string[1] < ' ')
2642 == (d->high->value.character.string[1]
2643 < ' ')))
2644 continue;
2646 break;
2650 if (d->high)
2652 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2653 && d->high->ts.type == BT_CHARACTER);
2654 if (d->high->value.character.length > 1)
2656 for (i = 1; i < d->high->value.character.length; i++)
2657 if (d->high->value.character.string[i] != ' ')
2658 break;
2659 if (i != d->high->value.character.length)
2660 break;
2664 if (d == NULL)
2666 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2668 for (c = code->block; c; c = c->block)
2670 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2672 tree low, high;
2673 tree label;
2674 gfc_char_t r;
2676 /* Assume it's the default case. */
2677 low = high = NULL_TREE;
2679 if (cp->low)
2681 /* CASE ('ab') or CASE ('ab':'az') will never match
2682 any length 1 character. */
2683 if (cp->low->value.character.length > 1
2684 && cp->low->value.character.string[1] != ' ')
2685 continue;
2687 if (cp->low->value.character.length > 0)
2688 r = cp->low->value.character.string[0];
2689 else
2690 r = ' ';
2691 low = build_int_cst (ctype, r);
2693 /* If there's only a lower bound, set the high bound
2694 to the maximum value of the case expression. */
2695 if (!cp->high)
2696 high = TYPE_MAX_VALUE (ctype);
2699 if (cp->high)
2701 if (!cp->low
2702 || (cp->low->value.character.string[0]
2703 != cp->high->value.character.string[0]))
2705 if (cp->high->value.character.length > 0)
2706 r = cp->high->value.character.string[0];
2707 else
2708 r = ' ';
2709 high = build_int_cst (ctype, r);
2712 /* Unbounded case. */
2713 if (!cp->low)
2714 low = TYPE_MIN_VALUE (ctype);
2717 /* Build a label. */
2718 label = gfc_build_label_decl (NULL_TREE);
2720 /* Add this case label.
2721 Add parameter 'label', make it match GCC backend. */
2722 tmp = build_case_label (low, high, label);
2723 gfc_add_expr_to_block (&body, tmp);
2726 /* Add the statements for this case. */
2727 tmp = gfc_trans_code (c->next);
2728 gfc_add_expr_to_block (&body, tmp);
2730 /* Break to the end of the construct. */
2731 tmp = build1_v (GOTO_EXPR, end_label);
2732 gfc_add_expr_to_block (&body, tmp);
2735 tmp = gfc_string_to_single_character (expr1se.string_length,
2736 expr1se.expr,
2737 code->expr1->ts.kind);
2738 case_num = gfc_create_var (ctype, "case_num");
2739 gfc_add_modify (&block, case_num, tmp);
2741 gfc_add_block_to_block (&block, &expr1se.post);
2743 tmp = gfc_finish_block (&body);
2744 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2745 case_num, tmp, NULL_TREE);
2746 gfc_add_expr_to_block (&block, tmp);
2748 tmp = build1_v (LABEL_EXPR, end_label);
2749 gfc_add_expr_to_block (&block, tmp);
2751 return gfc_finish_block (&block);
2755 if (code->expr1->ts.kind == 1)
2756 k = 0;
2757 else if (code->expr1->ts.kind == 4)
2758 k = 1;
2759 else
2760 gcc_unreachable ();
2762 if (select_struct[k] == NULL)
2764 tree *chain = NULL;
2765 select_struct[k] = make_node (RECORD_TYPE);
2767 if (code->expr1->ts.kind == 1)
2768 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2769 else if (code->expr1->ts.kind == 4)
2770 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2771 else
2772 gcc_unreachable ();
2774 #undef ADD_FIELD
2775 #define ADD_FIELD(NAME, TYPE) \
2776 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2777 get_identifier (stringize(NAME)), \
2778 TYPE, \
2779 &chain)
2781 ADD_FIELD (string1, pchartype);
2782 ADD_FIELD (string1_len, gfc_charlen_type_node);
2784 ADD_FIELD (string2, pchartype);
2785 ADD_FIELD (string2_len, gfc_charlen_type_node);
2787 ADD_FIELD (target, integer_type_node);
2788 #undef ADD_FIELD
2790 gfc_finish_type (select_struct[k]);
2793 n = 0;
2794 for (d = cp; d; d = d->right)
2795 d->n = n++;
2797 for (c = code->block; c; c = c->block)
2799 for (d = c->ext.block.case_list; d; d = d->next)
2801 label = gfc_build_label_decl (NULL_TREE);
2802 tmp = build_case_label ((d->low == NULL && d->high == NULL)
2803 ? NULL
2804 : build_int_cst (integer_type_node, d->n),
2805 NULL, label);
2806 gfc_add_expr_to_block (&body, tmp);
2809 tmp = gfc_trans_code (c->next);
2810 gfc_add_expr_to_block (&body, tmp);
2812 tmp = build1_v (GOTO_EXPR, end_label);
2813 gfc_add_expr_to_block (&body, tmp);
2816 /* Generate the structure describing the branches */
2817 for (d = cp; d; d = d->right)
2819 vec<constructor_elt, va_gc> *node = NULL;
2821 gfc_init_se (&se, NULL);
2823 if (d->low == NULL)
2825 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2826 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2828 else
2830 gfc_conv_expr_reference (&se, d->low);
2832 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2833 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2836 if (d->high == NULL)
2838 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2839 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2841 else
2843 gfc_init_se (&se, NULL);
2844 gfc_conv_expr_reference (&se, d->high);
2846 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
2847 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
2850 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
2851 build_int_cst (integer_type_node, d->n));
2853 tmp = build_constructor (select_struct[k], node);
2854 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
2857 type = build_array_type (select_struct[k],
2858 build_index_type (size_int (n-1)));
2860 init = build_constructor (type, inits);
2861 TREE_CONSTANT (init) = 1;
2862 TREE_STATIC (init) = 1;
2863 /* Create a static variable to hold the jump table. */
2864 tmp = gfc_create_var (type, "jumptable");
2865 TREE_CONSTANT (tmp) = 1;
2866 TREE_STATIC (tmp) = 1;
2867 TREE_READONLY (tmp) = 1;
2868 DECL_INITIAL (tmp) = init;
2869 init = tmp;
2871 /* Build the library call */
2872 init = gfc_build_addr_expr (pvoid_type_node, init);
2874 if (code->expr1->ts.kind == 1)
2875 fndecl = gfor_fndecl_select_string;
2876 else if (code->expr1->ts.kind == 4)
2877 fndecl = gfor_fndecl_select_string_char4;
2878 else
2879 gcc_unreachable ();
2881 tmp = build_call_expr_loc (input_location,
2882 fndecl, 4, init,
2883 build_int_cst (gfc_charlen_type_node, n),
2884 expr1se.expr, expr1se.string_length);
2885 case_num = gfc_create_var (integer_type_node, "case_num");
2886 gfc_add_modify (&block, case_num, tmp);
2888 gfc_add_block_to_block (&block, &expr1se.post);
2890 tmp = gfc_finish_block (&body);
2891 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2892 case_num, tmp, NULL_TREE);
2893 gfc_add_expr_to_block (&block, tmp);
2895 tmp = build1_v (LABEL_EXPR, end_label);
2896 gfc_add_expr_to_block (&block, tmp);
2898 return gfc_finish_block (&block);
2902 /* Translate the three variants of the SELECT CASE construct.
2904 SELECT CASEs with INTEGER case expressions can be translated to an
2905 equivalent GENERIC switch statement, and for LOGICAL case
2906 expressions we build one or two if-else compares.
2908 SELECT CASEs with CHARACTER case expressions are a whole different
2909 story, because they don't exist in GENERIC. So we sort them and
2910 do a binary search at runtime.
2912 Fortran has no BREAK statement, and it does not allow jumps from
2913 one case block to another. That makes things a lot easier for
2914 the optimizers. */
2916 tree
2917 gfc_trans_select (gfc_code * code)
2919 stmtblock_t block;
2920 tree body;
2921 tree exit_label;
2923 gcc_assert (code && code->expr1);
2924 gfc_init_block (&block);
2926 /* Build the exit label and hang it in. */
2927 exit_label = gfc_build_label_decl (NULL_TREE);
2928 code->exit_label = exit_label;
2930 /* Empty SELECT constructs are legal. */
2931 if (code->block == NULL)
2932 body = build_empty_stmt (input_location);
2934 /* Select the correct translation function. */
2935 else
2936 switch (code->expr1->ts.type)
2938 case BT_LOGICAL:
2939 body = gfc_trans_logical_select (code);
2940 break;
2942 case BT_INTEGER:
2943 body = gfc_trans_integer_select (code);
2944 break;
2946 case BT_CHARACTER:
2947 body = gfc_trans_character_select (code);
2948 break;
2950 default:
2951 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
2952 /* Not reached */
2955 /* Build everything together. */
2956 gfc_add_expr_to_block (&block, body);
2957 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
2959 return gfc_finish_block (&block);
2963 /* Traversal function to substitute a replacement symtree if the symbol
2964 in the expression is the same as that passed. f == 2 signals that
2965 that variable itself is not to be checked - only the references.
2966 This group of functions is used when the variable expression in a
2967 FORALL assignment has internal references. For example:
2968 FORALL (i = 1:4) p(p(i)) = i
2969 The only recourse here is to store a copy of 'p' for the index
2970 expression. */
2972 static gfc_symtree *new_symtree;
2973 static gfc_symtree *old_symtree;
2975 static bool
2976 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
2978 if (expr->expr_type != EXPR_VARIABLE)
2979 return false;
2981 if (*f == 2)
2982 *f = 1;
2983 else if (expr->symtree->n.sym == sym)
2984 expr->symtree = new_symtree;
2986 return false;
2989 static void
2990 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
2992 gfc_traverse_expr (e, sym, forall_replace, f);
2995 static bool
2996 forall_restore (gfc_expr *expr,
2997 gfc_symbol *sym ATTRIBUTE_UNUSED,
2998 int *f ATTRIBUTE_UNUSED)
3000 if (expr->expr_type != EXPR_VARIABLE)
3001 return false;
3003 if (expr->symtree == new_symtree)
3004 expr->symtree = old_symtree;
3006 return false;
3009 static void
3010 forall_restore_symtree (gfc_expr *e)
3012 gfc_traverse_expr (e, NULL, forall_restore, 0);
3015 static void
3016 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3018 gfc_se tse;
3019 gfc_se rse;
3020 gfc_expr *e;
3021 gfc_symbol *new_sym;
3022 gfc_symbol *old_sym;
3023 gfc_symtree *root;
3024 tree tmp;
3026 /* Build a copy of the lvalue. */
3027 old_symtree = c->expr1->symtree;
3028 old_sym = old_symtree->n.sym;
3029 e = gfc_lval_expr_from_sym (old_sym);
3030 if (old_sym->attr.dimension)
3032 gfc_init_se (&tse, NULL);
3033 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3034 gfc_add_block_to_block (pre, &tse.pre);
3035 gfc_add_block_to_block (post, &tse.post);
3036 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3038 if (e->ts.type != BT_CHARACTER)
3040 /* Use the variable offset for the temporary. */
3041 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3042 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3045 else
3047 gfc_init_se (&tse, NULL);
3048 gfc_init_se (&rse, NULL);
3049 gfc_conv_expr (&rse, e);
3050 if (e->ts.type == BT_CHARACTER)
3052 tse.string_length = rse.string_length;
3053 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3054 tse.string_length);
3055 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3056 rse.string_length);
3057 gfc_add_block_to_block (pre, &tse.pre);
3058 gfc_add_block_to_block (post, &tse.post);
3060 else
3062 tmp = gfc_typenode_for_spec (&e->ts);
3063 tse.expr = gfc_create_var (tmp, "temp");
3066 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3067 e->expr_type == EXPR_VARIABLE, false);
3068 gfc_add_expr_to_block (pre, tmp);
3070 gfc_free_expr (e);
3072 /* Create a new symbol to represent the lvalue. */
3073 new_sym = gfc_new_symbol (old_sym->name, NULL);
3074 new_sym->ts = old_sym->ts;
3075 new_sym->attr.referenced = 1;
3076 new_sym->attr.temporary = 1;
3077 new_sym->attr.dimension = old_sym->attr.dimension;
3078 new_sym->attr.flavor = old_sym->attr.flavor;
3080 /* Use the temporary as the backend_decl. */
3081 new_sym->backend_decl = tse.expr;
3083 /* Create a fake symtree for it. */
3084 root = NULL;
3085 new_symtree = gfc_new_symtree (&root, old_sym->name);
3086 new_symtree->n.sym = new_sym;
3087 gcc_assert (new_symtree == root);
3089 /* Go through the expression reference replacing the old_symtree
3090 with the new. */
3091 forall_replace_symtree (c->expr1, old_sym, 2);
3093 /* Now we have made this temporary, we might as well use it for
3094 the right hand side. */
3095 forall_replace_symtree (c->expr2, old_sym, 1);
3099 /* Handles dependencies in forall assignments. */
3100 static int
3101 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3103 gfc_ref *lref;
3104 gfc_ref *rref;
3105 int need_temp;
3106 gfc_symbol *lsym;
3108 lsym = c->expr1->symtree->n.sym;
3109 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3111 /* Now check for dependencies within the 'variable'
3112 expression itself. These are treated by making a complete
3113 copy of variable and changing all the references to it
3114 point to the copy instead. Note that the shallow copy of
3115 the variable will not suffice for derived types with
3116 pointer components. We therefore leave these to their
3117 own devices. */
3118 if (lsym->ts.type == BT_DERIVED
3119 && lsym->ts.u.derived->attr.pointer_comp)
3120 return need_temp;
3122 new_symtree = NULL;
3123 if (find_forall_index (c->expr1, lsym, 2))
3125 forall_make_variable_temp (c, pre, post);
3126 need_temp = 0;
3129 /* Substrings with dependencies are treated in the same
3130 way. */
3131 if (c->expr1->ts.type == BT_CHARACTER
3132 && c->expr1->ref
3133 && c->expr2->expr_type == EXPR_VARIABLE
3134 && lsym == c->expr2->symtree->n.sym)
3136 for (lref = c->expr1->ref; lref; lref = lref->next)
3137 if (lref->type == REF_SUBSTRING)
3138 break;
3139 for (rref = c->expr2->ref; rref; rref = rref->next)
3140 if (rref->type == REF_SUBSTRING)
3141 break;
3143 if (rref && lref
3144 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3146 forall_make_variable_temp (c, pre, post);
3147 need_temp = 0;
3150 return need_temp;
3154 static void
3155 cleanup_forall_symtrees (gfc_code *c)
3157 forall_restore_symtree (c->expr1);
3158 forall_restore_symtree (c->expr2);
3159 free (new_symtree->n.sym);
3160 free (new_symtree);
3164 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3165 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3166 indicates whether we should generate code to test the FORALLs mask
3167 array. OUTER is the loop header to be used for initializing mask
3168 indices.
3170 The generated loop format is:
3171 count = (end - start + step) / step
3172 loopvar = start
3173 while (1)
3175 if (count <=0 )
3176 goto end_of_loop
3177 <body>
3178 loopvar += step
3179 count --
3181 end_of_loop: */
3183 static tree
3184 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3185 int mask_flag, stmtblock_t *outer)
3187 int n, nvar;
3188 tree tmp;
3189 tree cond;
3190 stmtblock_t block;
3191 tree exit_label;
3192 tree count;
3193 tree var, start, end, step;
3194 iter_info *iter;
3196 /* Initialize the mask index outside the FORALL nest. */
3197 if (mask_flag && forall_tmp->mask)
3198 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3200 iter = forall_tmp->this_loop;
3201 nvar = forall_tmp->nvar;
3202 for (n = 0; n < nvar; n++)
3204 var = iter->var;
3205 start = iter->start;
3206 end = iter->end;
3207 step = iter->step;
3209 exit_label = gfc_build_label_decl (NULL_TREE);
3210 TREE_USED (exit_label) = 1;
3212 /* The loop counter. */
3213 count = gfc_create_var (TREE_TYPE (var), "count");
3215 /* The body of the loop. */
3216 gfc_init_block (&block);
3218 /* The exit condition. */
3219 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3220 count, build_int_cst (TREE_TYPE (count), 0));
3221 if (forall_tmp->do_concurrent)
3222 cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3223 build_int_cst (integer_type_node,
3224 annot_expr_ivdep_kind));
3226 tmp = build1_v (GOTO_EXPR, exit_label);
3227 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3228 cond, tmp, build_empty_stmt (input_location));
3229 gfc_add_expr_to_block (&block, tmp);
3231 /* The main loop body. */
3232 gfc_add_expr_to_block (&block, body);
3234 /* Increment the loop variable. */
3235 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3236 step);
3237 gfc_add_modify (&block, var, tmp);
3239 /* Advance to the next mask element. Only do this for the
3240 innermost loop. */
3241 if (n == 0 && mask_flag && forall_tmp->mask)
3243 tree maskindex = forall_tmp->maskindex;
3244 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3245 maskindex, gfc_index_one_node);
3246 gfc_add_modify (&block, maskindex, tmp);
3249 /* Decrement the loop counter. */
3250 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3251 build_int_cst (TREE_TYPE (var), 1));
3252 gfc_add_modify (&block, count, tmp);
3254 body = gfc_finish_block (&block);
3256 /* Loop var initialization. */
3257 gfc_init_block (&block);
3258 gfc_add_modify (&block, var, start);
3261 /* Initialize the loop counter. */
3262 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3263 start);
3264 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3265 tmp);
3266 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3267 tmp, step);
3268 gfc_add_modify (&block, count, tmp);
3270 /* The loop expression. */
3271 tmp = build1_v (LOOP_EXPR, body);
3272 gfc_add_expr_to_block (&block, tmp);
3274 /* The exit label. */
3275 tmp = build1_v (LABEL_EXPR, exit_label);
3276 gfc_add_expr_to_block (&block, tmp);
3278 body = gfc_finish_block (&block);
3279 iter = iter->next;
3281 return body;
3285 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3286 is nonzero, the body is controlled by all masks in the forall nest.
3287 Otherwise, the innermost loop is not controlled by it's mask. This
3288 is used for initializing that mask. */
3290 static tree
3291 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3292 int mask_flag)
3294 tree tmp;
3295 stmtblock_t header;
3296 forall_info *forall_tmp;
3297 tree mask, maskindex;
3299 gfc_start_block (&header);
3301 forall_tmp = nested_forall_info;
3302 while (forall_tmp != NULL)
3304 /* Generate body with masks' control. */
3305 if (mask_flag)
3307 mask = forall_tmp->mask;
3308 maskindex = forall_tmp->maskindex;
3310 /* If a mask was specified make the assignment conditional. */
3311 if (mask)
3313 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3314 body = build3_v (COND_EXPR, tmp, body,
3315 build_empty_stmt (input_location));
3318 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3319 forall_tmp = forall_tmp->prev_nest;
3320 mask_flag = 1;
3323 gfc_add_expr_to_block (&header, body);
3324 return gfc_finish_block (&header);
3328 /* Allocate data for holding a temporary array. Returns either a local
3329 temporary array or a pointer variable. */
3331 static tree
3332 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3333 tree elem_type)
3335 tree tmpvar;
3336 tree type;
3337 tree tmp;
3339 if (INTEGER_CST_P (size))
3340 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3341 size, gfc_index_one_node);
3342 else
3343 tmp = NULL_TREE;
3345 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3346 type = build_array_type (elem_type, type);
3347 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3349 tmpvar = gfc_create_var (type, "temp");
3350 *pdata = NULL_TREE;
3352 else
3354 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3355 *pdata = convert (pvoid_type_node, tmpvar);
3357 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3358 gfc_add_modify (pblock, tmpvar, tmp);
3360 return tmpvar;
3364 /* Generate codes to copy the temporary to the actual lhs. */
3366 static tree
3367 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3368 tree count1, tree wheremask, bool invert)
3370 gfc_ss *lss;
3371 gfc_se lse, rse;
3372 stmtblock_t block, body;
3373 gfc_loopinfo loop1;
3374 tree tmp;
3375 tree wheremaskexpr;
3377 /* Walk the lhs. */
3378 lss = gfc_walk_expr (expr);
3380 if (lss == gfc_ss_terminator)
3382 gfc_start_block (&block);
3384 gfc_init_se (&lse, NULL);
3386 /* Translate the expression. */
3387 gfc_conv_expr (&lse, expr);
3389 /* Form the expression for the temporary. */
3390 tmp = gfc_build_array_ref (tmp1, count1, NULL);
3392 /* Use the scalar assignment as is. */
3393 gfc_add_block_to_block (&block, &lse.pre);
3394 gfc_add_modify (&block, lse.expr, tmp);
3395 gfc_add_block_to_block (&block, &lse.post);
3397 /* Increment the count1. */
3398 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3399 count1, gfc_index_one_node);
3400 gfc_add_modify (&block, count1, tmp);
3402 tmp = gfc_finish_block (&block);
3404 else
3406 gfc_start_block (&block);
3408 gfc_init_loopinfo (&loop1);
3409 gfc_init_se (&rse, NULL);
3410 gfc_init_se (&lse, NULL);
3412 /* Associate the lss with the loop. */
3413 gfc_add_ss_to_loop (&loop1, lss);
3415 /* Calculate the bounds of the scalarization. */
3416 gfc_conv_ss_startstride (&loop1);
3417 /* Setup the scalarizing loops. */
3418 gfc_conv_loop_setup (&loop1, &expr->where);
3420 gfc_mark_ss_chain_used (lss, 1);
3422 /* Start the scalarized loop body. */
3423 gfc_start_scalarized_body (&loop1, &body);
3425 /* Setup the gfc_se structures. */
3426 gfc_copy_loopinfo_to_se (&lse, &loop1);
3427 lse.ss = lss;
3429 /* Form the expression of the temporary. */
3430 if (lss != gfc_ss_terminator)
3431 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3432 /* Translate expr. */
3433 gfc_conv_expr (&lse, expr);
3435 /* Use the scalar assignment. */
3436 rse.string_length = lse.string_length;
3437 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, true, true);
3439 /* Form the mask expression according to the mask tree list. */
3440 if (wheremask)
3442 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3443 if (invert)
3444 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3445 TREE_TYPE (wheremaskexpr),
3446 wheremaskexpr);
3447 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3448 wheremaskexpr, tmp,
3449 build_empty_stmt (input_location));
3452 gfc_add_expr_to_block (&body, tmp);
3454 /* Increment count1. */
3455 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3456 count1, gfc_index_one_node);
3457 gfc_add_modify (&body, count1, tmp);
3459 /* Increment count3. */
3460 if (count3)
3462 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3463 gfc_array_index_type, count3,
3464 gfc_index_one_node);
3465 gfc_add_modify (&body, count3, tmp);
3468 /* Generate the copying loops. */
3469 gfc_trans_scalarizing_loops (&loop1, &body);
3470 gfc_add_block_to_block (&block, &loop1.pre);
3471 gfc_add_block_to_block (&block, &loop1.post);
3472 gfc_cleanup_loop (&loop1);
3474 tmp = gfc_finish_block (&block);
3476 return tmp;
3480 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3481 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3482 and should not be freed. WHEREMASK is the conditional execution mask
3483 whose sense may be inverted by INVERT. */
3485 static tree
3486 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3487 tree count1, gfc_ss *lss, gfc_ss *rss,
3488 tree wheremask, bool invert)
3490 stmtblock_t block, body1;
3491 gfc_loopinfo loop;
3492 gfc_se lse;
3493 gfc_se rse;
3494 tree tmp;
3495 tree wheremaskexpr;
3497 gfc_start_block (&block);
3499 gfc_init_se (&rse, NULL);
3500 gfc_init_se (&lse, NULL);
3502 if (lss == gfc_ss_terminator)
3504 gfc_init_block (&body1);
3505 gfc_conv_expr (&rse, expr2);
3506 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3508 else
3510 /* Initialize the loop. */
3511 gfc_init_loopinfo (&loop);
3513 /* We may need LSS to determine the shape of the expression. */
3514 gfc_add_ss_to_loop (&loop, lss);
3515 gfc_add_ss_to_loop (&loop, rss);
3517 gfc_conv_ss_startstride (&loop);
3518 gfc_conv_loop_setup (&loop, &expr2->where);
3520 gfc_mark_ss_chain_used (rss, 1);
3521 /* Start the loop body. */
3522 gfc_start_scalarized_body (&loop, &body1);
3524 /* Translate the expression. */
3525 gfc_copy_loopinfo_to_se (&rse, &loop);
3526 rse.ss = rss;
3527 gfc_conv_expr (&rse, expr2);
3529 /* Form the expression of the temporary. */
3530 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3533 /* Use the scalar assignment. */
3534 lse.string_length = rse.string_length;
3535 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3536 expr2->expr_type == EXPR_VARIABLE, false);
3538 /* Form the mask expression according to the mask tree list. */
3539 if (wheremask)
3541 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3542 if (invert)
3543 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3544 TREE_TYPE (wheremaskexpr),
3545 wheremaskexpr);
3546 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3547 wheremaskexpr, tmp,
3548 build_empty_stmt (input_location));
3551 gfc_add_expr_to_block (&body1, tmp);
3553 if (lss == gfc_ss_terminator)
3555 gfc_add_block_to_block (&block, &body1);
3557 /* Increment count1. */
3558 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3559 count1, gfc_index_one_node);
3560 gfc_add_modify (&block, count1, tmp);
3562 else
3564 /* Increment count1. */
3565 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3566 count1, gfc_index_one_node);
3567 gfc_add_modify (&body1, count1, tmp);
3569 /* Increment count3. */
3570 if (count3)
3572 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3573 gfc_array_index_type,
3574 count3, gfc_index_one_node);
3575 gfc_add_modify (&body1, count3, tmp);
3578 /* Generate the copying loops. */
3579 gfc_trans_scalarizing_loops (&loop, &body1);
3581 gfc_add_block_to_block (&block, &loop.pre);
3582 gfc_add_block_to_block (&block, &loop.post);
3584 gfc_cleanup_loop (&loop);
3585 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3586 as tree nodes in SS may not be valid in different scope. */
3589 tmp = gfc_finish_block (&block);
3590 return tmp;
3594 /* Calculate the size of temporary needed in the assignment inside forall.
3595 LSS and RSS are filled in this function. */
3597 static tree
3598 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3599 stmtblock_t * pblock,
3600 gfc_ss **lss, gfc_ss **rss)
3602 gfc_loopinfo loop;
3603 tree size;
3604 int i;
3605 int save_flag;
3606 tree tmp;
3608 *lss = gfc_walk_expr (expr1);
3609 *rss = NULL;
3611 size = gfc_index_one_node;
3612 if (*lss != gfc_ss_terminator)
3614 gfc_init_loopinfo (&loop);
3616 /* Walk the RHS of the expression. */
3617 *rss = gfc_walk_expr (expr2);
3618 if (*rss == gfc_ss_terminator)
3619 /* The rhs is scalar. Add a ss for the expression. */
3620 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3622 /* Associate the SS with the loop. */
3623 gfc_add_ss_to_loop (&loop, *lss);
3624 /* We don't actually need to add the rhs at this point, but it might
3625 make guessing the loop bounds a bit easier. */
3626 gfc_add_ss_to_loop (&loop, *rss);
3628 /* We only want the shape of the expression, not rest of the junk
3629 generated by the scalarizer. */
3630 loop.array_parameter = 1;
3632 /* Calculate the bounds of the scalarization. */
3633 save_flag = gfc_option.rtcheck;
3634 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3635 gfc_conv_ss_startstride (&loop);
3636 gfc_option.rtcheck = save_flag;
3637 gfc_conv_loop_setup (&loop, &expr2->where);
3639 /* Figure out how many elements we need. */
3640 for (i = 0; i < loop.dimen; i++)
3642 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3643 gfc_array_index_type,
3644 gfc_index_one_node, loop.from[i]);
3645 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3646 gfc_array_index_type, tmp, loop.to[i]);
3647 size = fold_build2_loc (input_location, MULT_EXPR,
3648 gfc_array_index_type, size, tmp);
3650 gfc_add_block_to_block (pblock, &loop.pre);
3651 size = gfc_evaluate_now (size, pblock);
3652 gfc_add_block_to_block (pblock, &loop.post);
3654 /* TODO: write a function that cleans up a loopinfo without freeing
3655 the SS chains. Currently a NOP. */
3658 return size;
3662 /* Calculate the overall iterator number of the nested forall construct.
3663 This routine actually calculates the number of times the body of the
3664 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3665 that by the expression INNER_SIZE. The BLOCK argument specifies the
3666 block in which to calculate the result, and the optional INNER_SIZE_BODY
3667 argument contains any statements that need to executed (inside the loop)
3668 to initialize or calculate INNER_SIZE. */
3670 static tree
3671 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3672 stmtblock_t *inner_size_body, stmtblock_t *block)
3674 forall_info *forall_tmp = nested_forall_info;
3675 tree tmp, number;
3676 stmtblock_t body;
3678 /* We can eliminate the innermost unconditional loops with constant
3679 array bounds. */
3680 if (INTEGER_CST_P (inner_size))
3682 while (forall_tmp
3683 && !forall_tmp->mask
3684 && INTEGER_CST_P (forall_tmp->size))
3686 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3687 gfc_array_index_type,
3688 inner_size, forall_tmp->size);
3689 forall_tmp = forall_tmp->prev_nest;
3692 /* If there are no loops left, we have our constant result. */
3693 if (!forall_tmp)
3694 return inner_size;
3697 /* Otherwise, create a temporary variable to compute the result. */
3698 number = gfc_create_var (gfc_array_index_type, "num");
3699 gfc_add_modify (block, number, gfc_index_zero_node);
3701 gfc_start_block (&body);
3702 if (inner_size_body)
3703 gfc_add_block_to_block (&body, inner_size_body);
3704 if (forall_tmp)
3705 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3706 gfc_array_index_type, number, inner_size);
3707 else
3708 tmp = inner_size;
3709 gfc_add_modify (&body, number, tmp);
3710 tmp = gfc_finish_block (&body);
3712 /* Generate loops. */
3713 if (forall_tmp != NULL)
3714 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3716 gfc_add_expr_to_block (block, tmp);
3718 return number;
3722 /* Allocate temporary for forall construct. SIZE is the size of temporary
3723 needed. PTEMP1 is returned for space free. */
3725 static tree
3726 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3727 tree * ptemp1)
3729 tree bytesize;
3730 tree unit;
3731 tree tmp;
3733 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3734 if (!integer_onep (unit))
3735 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3736 gfc_array_index_type, size, unit);
3737 else
3738 bytesize = size;
3740 *ptemp1 = NULL;
3741 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3743 if (*ptemp1)
3744 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3745 return tmp;
3749 /* Allocate temporary for forall construct according to the information in
3750 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3751 assignment inside forall. PTEMP1 is returned for space free. */
3753 static tree
3754 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3755 tree inner_size, stmtblock_t * inner_size_body,
3756 stmtblock_t * block, tree * ptemp1)
3758 tree size;
3760 /* Calculate the total size of temporary needed in forall construct. */
3761 size = compute_overall_iter_number (nested_forall_info, inner_size,
3762 inner_size_body, block);
3764 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3768 /* Handle assignments inside forall which need temporary.
3770 forall (i=start:end:stride; maskexpr)
3771 e<i> = f<i>
3772 end forall
3773 (where e,f<i> are arbitrary expressions possibly involving i
3774 and there is a dependency between e<i> and f<i>)
3775 Translates to:
3776 masktmp(:) = maskexpr(:)
3778 maskindex = 0;
3779 count1 = 0;
3780 num = 0;
3781 for (i = start; i <= end; i += stride)
3782 num += SIZE (f<i>)
3783 count1 = 0;
3784 ALLOCATE (tmp(num))
3785 for (i = start; i <= end; i += stride)
3787 if (masktmp[maskindex++])
3788 tmp[count1++] = f<i>
3790 maskindex = 0;
3791 count1 = 0;
3792 for (i = start; i <= end; i += stride)
3794 if (masktmp[maskindex++])
3795 e<i> = tmp[count1++]
3797 DEALLOCATE (tmp)
3799 static void
3800 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3801 tree wheremask, bool invert,
3802 forall_info * nested_forall_info,
3803 stmtblock_t * block)
3805 tree type;
3806 tree inner_size;
3807 gfc_ss *lss, *rss;
3808 tree count, count1;
3809 tree tmp, tmp1;
3810 tree ptemp1;
3811 stmtblock_t inner_size_body;
3813 /* Create vars. count1 is the current iterator number of the nested
3814 forall. */
3815 count1 = gfc_create_var (gfc_array_index_type, "count1");
3817 /* Count is the wheremask index. */
3818 if (wheremask)
3820 count = gfc_create_var (gfc_array_index_type, "count");
3821 gfc_add_modify (block, count, gfc_index_zero_node);
3823 else
3824 count = NULL;
3826 /* Initialize count1. */
3827 gfc_add_modify (block, count1, gfc_index_zero_node);
3829 /* Calculate the size of temporary needed in the assignment. Return loop, lss
3830 and rss which are used in function generate_loop_for_rhs_to_temp(). */
3831 gfc_init_block (&inner_size_body);
3832 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
3833 &lss, &rss);
3835 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3836 if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->length)
3838 if (!expr1->ts.u.cl->backend_decl)
3840 gfc_se tse;
3841 gfc_init_se (&tse, NULL);
3842 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
3843 expr1->ts.u.cl->backend_decl = tse.expr;
3845 type = gfc_get_character_type_len (gfc_default_character_kind,
3846 expr1->ts.u.cl->backend_decl);
3848 else
3849 type = gfc_typenode_for_spec (&expr1->ts);
3851 /* Allocate temporary for nested forall construct according to the
3852 information in nested_forall_info and inner_size. */
3853 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
3854 &inner_size_body, block, &ptemp1);
3856 /* Generate codes to copy rhs to the temporary . */
3857 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
3858 wheremask, invert);
3860 /* Generate body and loops according to the information in
3861 nested_forall_info. */
3862 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3863 gfc_add_expr_to_block (block, tmp);
3865 /* Reset count1. */
3866 gfc_add_modify (block, count1, gfc_index_zero_node);
3868 /* Reset count. */
3869 if (wheremask)
3870 gfc_add_modify (block, count, gfc_index_zero_node);
3872 /* Generate codes to copy the temporary to lhs. */
3873 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
3874 wheremask, invert);
3876 /* Generate body and loops according to the information in
3877 nested_forall_info. */
3878 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3879 gfc_add_expr_to_block (block, tmp);
3881 if (ptemp1)
3883 /* Free the temporary. */
3884 tmp = gfc_call_free (ptemp1);
3885 gfc_add_expr_to_block (block, tmp);
3890 /* Translate pointer assignment inside FORALL which need temporary. */
3892 static void
3893 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3894 forall_info * nested_forall_info,
3895 stmtblock_t * block)
3897 tree type;
3898 tree inner_size;
3899 gfc_ss *lss, *rss;
3900 gfc_se lse;
3901 gfc_se rse;
3902 gfc_array_info *info;
3903 gfc_loopinfo loop;
3904 tree desc;
3905 tree parm;
3906 tree parmtype;
3907 stmtblock_t body;
3908 tree count;
3909 tree tmp, tmp1, ptemp1;
3911 count = gfc_create_var (gfc_array_index_type, "count");
3912 gfc_add_modify (block, count, gfc_index_zero_node);
3914 inner_size = gfc_index_one_node;
3915 lss = gfc_walk_expr (expr1);
3916 rss = gfc_walk_expr (expr2);
3917 if (lss == gfc_ss_terminator)
3919 type = gfc_typenode_for_spec (&expr1->ts);
3920 type = build_pointer_type (type);
3922 /* Allocate temporary for nested forall construct according to the
3923 information in nested_forall_info and inner_size. */
3924 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
3925 inner_size, NULL, block, &ptemp1);
3926 gfc_start_block (&body);
3927 gfc_init_se (&lse, NULL);
3928 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3929 gfc_init_se (&rse, NULL);
3930 rse.want_pointer = 1;
3931 gfc_conv_expr (&rse, expr2);
3932 gfc_add_block_to_block (&body, &rse.pre);
3933 gfc_add_modify (&body, lse.expr,
3934 fold_convert (TREE_TYPE (lse.expr), rse.expr));
3935 gfc_add_block_to_block (&body, &rse.post);
3937 /* Increment count. */
3938 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3939 count, gfc_index_one_node);
3940 gfc_add_modify (&body, count, tmp);
3942 tmp = gfc_finish_block (&body);
3944 /* Generate body and loops according to the information in
3945 nested_forall_info. */
3946 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3947 gfc_add_expr_to_block (block, tmp);
3949 /* Reset count. */
3950 gfc_add_modify (block, count, gfc_index_zero_node);
3952 gfc_start_block (&body);
3953 gfc_init_se (&lse, NULL);
3954 gfc_init_se (&rse, NULL);
3955 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
3956 lse.want_pointer = 1;
3957 gfc_conv_expr (&lse, expr1);
3958 gfc_add_block_to_block (&body, &lse.pre);
3959 gfc_add_modify (&body, lse.expr, rse.expr);
3960 gfc_add_block_to_block (&body, &lse.post);
3961 /* Increment count. */
3962 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3963 count, gfc_index_one_node);
3964 gfc_add_modify (&body, count, tmp);
3965 tmp = gfc_finish_block (&body);
3967 /* Generate body and loops according to the information in
3968 nested_forall_info. */
3969 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3970 gfc_add_expr_to_block (block, tmp);
3972 else
3974 gfc_init_loopinfo (&loop);
3976 /* Associate the SS with the loop. */
3977 gfc_add_ss_to_loop (&loop, rss);
3979 /* Setup the scalarizing loops and bounds. */
3980 gfc_conv_ss_startstride (&loop);
3982 gfc_conv_loop_setup (&loop, &expr2->where);
3984 info = &rss->info->data.array;
3985 desc = info->descriptor;
3987 /* Make a new descriptor. */
3988 parmtype = gfc_get_element_type (TREE_TYPE (desc));
3989 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
3990 loop.from, loop.to, 1,
3991 GFC_ARRAY_UNKNOWN, true);
3993 /* Allocate temporary for nested forall construct. */
3994 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
3995 inner_size, NULL, block, &ptemp1);
3996 gfc_start_block (&body);
3997 gfc_init_se (&lse, NULL);
3998 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3999 lse.direct_byref = 1;
4000 gfc_conv_expr_descriptor (&lse, expr2);
4002 gfc_add_block_to_block (&body, &lse.pre);
4003 gfc_add_block_to_block (&body, &lse.post);
4005 /* Increment count. */
4006 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4007 count, gfc_index_one_node);
4008 gfc_add_modify (&body, count, tmp);
4010 tmp = gfc_finish_block (&body);
4012 /* Generate body and loops according to the information in
4013 nested_forall_info. */
4014 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4015 gfc_add_expr_to_block (block, tmp);
4017 /* Reset count. */
4018 gfc_add_modify (block, count, gfc_index_zero_node);
4020 parm = gfc_build_array_ref (tmp1, count, NULL);
4021 gfc_init_se (&lse, NULL);
4022 gfc_conv_expr_descriptor (&lse, expr1);
4023 gfc_add_modify (&lse.pre, lse.expr, parm);
4024 gfc_start_block (&body);
4025 gfc_add_block_to_block (&body, &lse.pre);
4026 gfc_add_block_to_block (&body, &lse.post);
4028 /* Increment count. */
4029 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4030 count, gfc_index_one_node);
4031 gfc_add_modify (&body, count, tmp);
4033 tmp = gfc_finish_block (&body);
4035 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4036 gfc_add_expr_to_block (block, tmp);
4038 /* Free the temporary. */
4039 if (ptemp1)
4041 tmp = gfc_call_free (ptemp1);
4042 gfc_add_expr_to_block (block, tmp);
4047 /* FORALL and WHERE statements are really nasty, especially when you nest
4048 them. All the rhs of a forall assignment must be evaluated before the
4049 actual assignments are performed. Presumably this also applies to all the
4050 assignments in an inner where statement. */
4052 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4053 linear array, relying on the fact that we process in the same order in all
4054 loops.
4056 forall (i=start:end:stride; maskexpr)
4057 e<i> = f<i>
4058 g<i> = h<i>
4059 end forall
4060 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4061 Translates to:
4062 count = ((end + 1 - start) / stride)
4063 masktmp(:) = maskexpr(:)
4065 maskindex = 0;
4066 for (i = start; i <= end; i += stride)
4068 if (masktmp[maskindex++])
4069 e<i> = f<i>
4071 maskindex = 0;
4072 for (i = start; i <= end; i += stride)
4074 if (masktmp[maskindex++])
4075 g<i> = h<i>
4078 Note that this code only works when there are no dependencies.
4079 Forall loop with array assignments and data dependencies are a real pain,
4080 because the size of the temporary cannot always be determined before the
4081 loop is executed. This problem is compounded by the presence of nested
4082 FORALL constructs.
4085 static tree
4086 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4088 stmtblock_t pre;
4089 stmtblock_t post;
4090 stmtblock_t block;
4091 stmtblock_t body;
4092 tree *var;
4093 tree *start;
4094 tree *end;
4095 tree *step;
4096 gfc_expr **varexpr;
4097 tree tmp;
4098 tree assign;
4099 tree size;
4100 tree maskindex;
4101 tree mask;
4102 tree pmask;
4103 tree cycle_label = NULL_TREE;
4104 int n;
4105 int nvar;
4106 int need_temp;
4107 gfc_forall_iterator *fa;
4108 gfc_se se;
4109 gfc_code *c;
4110 gfc_saved_var *saved_vars;
4111 iter_info *this_forall;
4112 forall_info *info;
4113 bool need_mask;
4115 /* Do nothing if the mask is false. */
4116 if (code->expr1
4117 && code->expr1->expr_type == EXPR_CONSTANT
4118 && !code->expr1->value.logical)
4119 return build_empty_stmt (input_location);
4121 n = 0;
4122 /* Count the FORALL index number. */
4123 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4124 n++;
4125 nvar = n;
4127 /* Allocate the space for var, start, end, step, varexpr. */
4128 var = XCNEWVEC (tree, nvar);
4129 start = XCNEWVEC (tree, nvar);
4130 end = XCNEWVEC (tree, nvar);
4131 step = XCNEWVEC (tree, nvar);
4132 varexpr = XCNEWVEC (gfc_expr *, nvar);
4133 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4135 /* Allocate the space for info. */
4136 info = XCNEW (forall_info);
4138 gfc_start_block (&pre);
4139 gfc_init_block (&post);
4140 gfc_init_block (&block);
4142 n = 0;
4143 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4145 gfc_symbol *sym = fa->var->symtree->n.sym;
4147 /* Allocate space for this_forall. */
4148 this_forall = XCNEW (iter_info);
4150 /* Create a temporary variable for the FORALL index. */
4151 tmp = gfc_typenode_for_spec (&sym->ts);
4152 var[n] = gfc_create_var (tmp, sym->name);
4153 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4155 /* Record it in this_forall. */
4156 this_forall->var = var[n];
4158 /* Replace the index symbol's backend_decl with the temporary decl. */
4159 sym->backend_decl = var[n];
4161 /* Work out the start, end and stride for the loop. */
4162 gfc_init_se (&se, NULL);
4163 gfc_conv_expr_val (&se, fa->start);
4164 /* Record it in this_forall. */
4165 this_forall->start = se.expr;
4166 gfc_add_block_to_block (&block, &se.pre);
4167 start[n] = se.expr;
4169 gfc_init_se (&se, NULL);
4170 gfc_conv_expr_val (&se, fa->end);
4171 /* Record it in this_forall. */
4172 this_forall->end = se.expr;
4173 gfc_make_safe_expr (&se);
4174 gfc_add_block_to_block (&block, &se.pre);
4175 end[n] = se.expr;
4177 gfc_init_se (&se, NULL);
4178 gfc_conv_expr_val (&se, fa->stride);
4179 /* Record it in this_forall. */
4180 this_forall->step = se.expr;
4181 gfc_make_safe_expr (&se);
4182 gfc_add_block_to_block (&block, &se.pre);
4183 step[n] = se.expr;
4185 /* Set the NEXT field of this_forall to NULL. */
4186 this_forall->next = NULL;
4187 /* Link this_forall to the info construct. */
4188 if (info->this_loop)
4190 iter_info *iter_tmp = info->this_loop;
4191 while (iter_tmp->next != NULL)
4192 iter_tmp = iter_tmp->next;
4193 iter_tmp->next = this_forall;
4195 else
4196 info->this_loop = this_forall;
4198 n++;
4200 nvar = n;
4202 /* Calculate the size needed for the current forall level. */
4203 size = gfc_index_one_node;
4204 for (n = 0; n < nvar; n++)
4206 /* size = (end + step - start) / step. */
4207 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4208 step[n], start[n]);
4209 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4210 end[n], tmp);
4211 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4212 tmp, step[n]);
4213 tmp = convert (gfc_array_index_type, tmp);
4215 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4216 size, tmp);
4219 /* Record the nvar and size of current forall level. */
4220 info->nvar = nvar;
4221 info->size = size;
4223 if (code->expr1)
4225 /* If the mask is .true., consider the FORALL unconditional. */
4226 if (code->expr1->expr_type == EXPR_CONSTANT
4227 && code->expr1->value.logical)
4228 need_mask = false;
4229 else
4230 need_mask = true;
4232 else
4233 need_mask = false;
4235 /* First we need to allocate the mask. */
4236 if (need_mask)
4238 /* As the mask array can be very big, prefer compact boolean types. */
4239 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4240 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4241 size, NULL, &block, &pmask);
4242 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4244 /* Record them in the info structure. */
4245 info->maskindex = maskindex;
4246 info->mask = mask;
4248 else
4250 /* No mask was specified. */
4251 maskindex = NULL_TREE;
4252 mask = pmask = NULL_TREE;
4255 /* Link the current forall level to nested_forall_info. */
4256 info->prev_nest = nested_forall_info;
4257 nested_forall_info = info;
4259 /* Copy the mask into a temporary variable if required.
4260 For now we assume a mask temporary is needed. */
4261 if (need_mask)
4263 /* As the mask array can be very big, prefer compact boolean types. */
4264 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4266 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4268 /* Start of mask assignment loop body. */
4269 gfc_start_block (&body);
4271 /* Evaluate the mask expression. */
4272 gfc_init_se (&se, NULL);
4273 gfc_conv_expr_val (&se, code->expr1);
4274 gfc_add_block_to_block (&body, &se.pre);
4276 /* Store the mask. */
4277 se.expr = convert (mask_type, se.expr);
4279 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4280 gfc_add_modify (&body, tmp, se.expr);
4282 /* Advance to the next mask element. */
4283 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4284 maskindex, gfc_index_one_node);
4285 gfc_add_modify (&body, maskindex, tmp);
4287 /* Generate the loops. */
4288 tmp = gfc_finish_block (&body);
4289 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4290 gfc_add_expr_to_block (&block, tmp);
4293 if (code->op == EXEC_DO_CONCURRENT)
4295 gfc_init_block (&body);
4296 cycle_label = gfc_build_label_decl (NULL_TREE);
4297 code->cycle_label = cycle_label;
4298 tmp = gfc_trans_code (code->block->next);
4299 gfc_add_expr_to_block (&body, tmp);
4301 if (TREE_USED (cycle_label))
4303 tmp = build1_v (LABEL_EXPR, cycle_label);
4304 gfc_add_expr_to_block (&body, tmp);
4307 tmp = gfc_finish_block (&body);
4308 nested_forall_info->do_concurrent = true;
4309 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4310 gfc_add_expr_to_block (&block, tmp);
4311 goto done;
4314 c = code->block->next;
4316 /* TODO: loop merging in FORALL statements. */
4317 /* Now that we've got a copy of the mask, generate the assignment loops. */
4318 while (c)
4320 switch (c->op)
4322 case EXEC_ASSIGN:
4323 /* A scalar or array assignment. DO the simple check for
4324 lhs to rhs dependencies. These make a temporary for the
4325 rhs and form a second forall block to copy to variable. */
4326 need_temp = check_forall_dependencies(c, &pre, &post);
4328 /* Temporaries due to array assignment data dependencies introduce
4329 no end of problems. */
4330 if (need_temp)
4331 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4332 nested_forall_info, &block);
4333 else
4335 /* Use the normal assignment copying routines. */
4336 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4338 /* Generate body and loops. */
4339 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4340 assign, 1);
4341 gfc_add_expr_to_block (&block, tmp);
4344 /* Cleanup any temporary symtrees that have been made to deal
4345 with dependencies. */
4346 if (new_symtree)
4347 cleanup_forall_symtrees (c);
4349 break;
4351 case EXEC_WHERE:
4352 /* Translate WHERE or WHERE construct nested in FORALL. */
4353 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4354 break;
4356 /* Pointer assignment inside FORALL. */
4357 case EXEC_POINTER_ASSIGN:
4358 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4359 if (need_temp)
4360 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4361 nested_forall_info, &block);
4362 else
4364 /* Use the normal assignment copying routines. */
4365 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4367 /* Generate body and loops. */
4368 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4369 assign, 1);
4370 gfc_add_expr_to_block (&block, tmp);
4372 break;
4374 case EXEC_FORALL:
4375 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4376 gfc_add_expr_to_block (&block, tmp);
4377 break;
4379 /* Explicit subroutine calls are prevented by the frontend but interface
4380 assignments can legitimately produce them. */
4381 case EXEC_ASSIGN_CALL:
4382 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4383 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4384 gfc_add_expr_to_block (&block, tmp);
4385 break;
4387 default:
4388 gcc_unreachable ();
4391 c = c->next;
4394 done:
4395 /* Restore the original index variables. */
4396 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4397 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4399 /* Free the space for var, start, end, step, varexpr. */
4400 free (var);
4401 free (start);
4402 free (end);
4403 free (step);
4404 free (varexpr);
4405 free (saved_vars);
4407 for (this_forall = info->this_loop; this_forall;)
4409 iter_info *next = this_forall->next;
4410 free (this_forall);
4411 this_forall = next;
4414 /* Free the space for this forall_info. */
4415 free (info);
4417 if (pmask)
4419 /* Free the temporary for the mask. */
4420 tmp = gfc_call_free (pmask);
4421 gfc_add_expr_to_block (&block, tmp);
4423 if (maskindex)
4424 pushdecl (maskindex);
4426 gfc_add_block_to_block (&pre, &block);
4427 gfc_add_block_to_block (&pre, &post);
4429 return gfc_finish_block (&pre);
4433 /* Translate the FORALL statement or construct. */
4435 tree gfc_trans_forall (gfc_code * code)
4437 return gfc_trans_forall_1 (code, NULL);
4441 /* Translate the DO CONCURRENT construct. */
4443 tree gfc_trans_do_concurrent (gfc_code * code)
4445 return gfc_trans_forall_1 (code, NULL);
4449 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4450 If the WHERE construct is nested in FORALL, compute the overall temporary
4451 needed by the WHERE mask expression multiplied by the iterator number of
4452 the nested forall.
4453 ME is the WHERE mask expression.
4454 MASK is the current execution mask upon input, whose sense may or may
4455 not be inverted as specified by the INVERT argument.
4456 CMASK is the updated execution mask on output, or NULL if not required.
4457 PMASK is the pending execution mask on output, or NULL if not required.
4458 BLOCK is the block in which to place the condition evaluation loops. */
4460 static void
4461 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4462 tree mask, bool invert, tree cmask, tree pmask,
4463 tree mask_type, stmtblock_t * block)
4465 tree tmp, tmp1;
4466 gfc_ss *lss, *rss;
4467 gfc_loopinfo loop;
4468 stmtblock_t body, body1;
4469 tree count, cond, mtmp;
4470 gfc_se lse, rse;
4472 gfc_init_loopinfo (&loop);
4474 lss = gfc_walk_expr (me);
4475 rss = gfc_walk_expr (me);
4477 /* Variable to index the temporary. */
4478 count = gfc_create_var (gfc_array_index_type, "count");
4479 /* Initialize count. */
4480 gfc_add_modify (block, count, gfc_index_zero_node);
4482 gfc_start_block (&body);
4484 gfc_init_se (&rse, NULL);
4485 gfc_init_se (&lse, NULL);
4487 if (lss == gfc_ss_terminator)
4489 gfc_init_block (&body1);
4491 else
4493 /* Initialize the loop. */
4494 gfc_init_loopinfo (&loop);
4496 /* We may need LSS to determine the shape of the expression. */
4497 gfc_add_ss_to_loop (&loop, lss);
4498 gfc_add_ss_to_loop (&loop, rss);
4500 gfc_conv_ss_startstride (&loop);
4501 gfc_conv_loop_setup (&loop, &me->where);
4503 gfc_mark_ss_chain_used (rss, 1);
4504 /* Start the loop body. */
4505 gfc_start_scalarized_body (&loop, &body1);
4507 /* Translate the expression. */
4508 gfc_copy_loopinfo_to_se (&rse, &loop);
4509 rse.ss = rss;
4510 gfc_conv_expr (&rse, me);
4513 /* Variable to evaluate mask condition. */
4514 cond = gfc_create_var (mask_type, "cond");
4515 if (mask && (cmask || pmask))
4516 mtmp = gfc_create_var (mask_type, "mask");
4517 else mtmp = NULL_TREE;
4519 gfc_add_block_to_block (&body1, &lse.pre);
4520 gfc_add_block_to_block (&body1, &rse.pre);
4522 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4524 if (mask && (cmask || pmask))
4526 tmp = gfc_build_array_ref (mask, count, NULL);
4527 if (invert)
4528 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4529 gfc_add_modify (&body1, mtmp, tmp);
4532 if (cmask)
4534 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4535 tmp = cond;
4536 if (mask)
4537 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4538 mtmp, tmp);
4539 gfc_add_modify (&body1, tmp1, tmp);
4542 if (pmask)
4544 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4545 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4546 if (mask)
4547 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4548 tmp);
4549 gfc_add_modify (&body1, tmp1, tmp);
4552 gfc_add_block_to_block (&body1, &lse.post);
4553 gfc_add_block_to_block (&body1, &rse.post);
4555 if (lss == gfc_ss_terminator)
4557 gfc_add_block_to_block (&body, &body1);
4559 else
4561 /* Increment count. */
4562 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4563 count, gfc_index_one_node);
4564 gfc_add_modify (&body1, count, tmp1);
4566 /* Generate the copying loops. */
4567 gfc_trans_scalarizing_loops (&loop, &body1);
4569 gfc_add_block_to_block (&body, &loop.pre);
4570 gfc_add_block_to_block (&body, &loop.post);
4572 gfc_cleanup_loop (&loop);
4573 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4574 as tree nodes in SS may not be valid in different scope. */
4577 tmp1 = gfc_finish_block (&body);
4578 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4579 if (nested_forall_info != NULL)
4580 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4582 gfc_add_expr_to_block (block, tmp1);
4586 /* Translate an assignment statement in a WHERE statement or construct
4587 statement. The MASK expression is used to control which elements
4588 of EXPR1 shall be assigned. The sense of MASK is specified by
4589 INVERT. */
4591 static tree
4592 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4593 tree mask, bool invert,
4594 tree count1, tree count2,
4595 gfc_code *cnext)
4597 gfc_se lse;
4598 gfc_se rse;
4599 gfc_ss *lss;
4600 gfc_ss *lss_section;
4601 gfc_ss *rss;
4603 gfc_loopinfo loop;
4604 tree tmp;
4605 stmtblock_t block;
4606 stmtblock_t body;
4607 tree index, maskexpr;
4609 /* A defined assignment. */
4610 if (cnext && cnext->resolved_sym)
4611 return gfc_trans_call (cnext, true, mask, count1, invert);
4613 #if 0
4614 /* TODO: handle this special case.
4615 Special case a single function returning an array. */
4616 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4618 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4619 if (tmp)
4620 return tmp;
4622 #endif
4624 /* Assignment of the form lhs = rhs. */
4625 gfc_start_block (&block);
4627 gfc_init_se (&lse, NULL);
4628 gfc_init_se (&rse, NULL);
4630 /* Walk the lhs. */
4631 lss = gfc_walk_expr (expr1);
4632 rss = NULL;
4634 /* In each where-assign-stmt, the mask-expr and the variable being
4635 defined shall be arrays of the same shape. */
4636 gcc_assert (lss != gfc_ss_terminator);
4638 /* The assignment needs scalarization. */
4639 lss_section = lss;
4641 /* Find a non-scalar SS from the lhs. */
4642 while (lss_section != gfc_ss_terminator
4643 && lss_section->info->type != GFC_SS_SECTION)
4644 lss_section = lss_section->next;
4646 gcc_assert (lss_section != gfc_ss_terminator);
4648 /* Initialize the scalarizer. */
4649 gfc_init_loopinfo (&loop);
4651 /* Walk the rhs. */
4652 rss = gfc_walk_expr (expr2);
4653 if (rss == gfc_ss_terminator)
4655 /* The rhs is scalar. Add a ss for the expression. */
4656 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4657 rss->info->where = 1;
4660 /* Associate the SS with the loop. */
4661 gfc_add_ss_to_loop (&loop, lss);
4662 gfc_add_ss_to_loop (&loop, rss);
4664 /* Calculate the bounds of the scalarization. */
4665 gfc_conv_ss_startstride (&loop);
4667 /* Resolve any data dependencies in the statement. */
4668 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4670 /* Setup the scalarizing loops. */
4671 gfc_conv_loop_setup (&loop, &expr2->where);
4673 /* Setup the gfc_se structures. */
4674 gfc_copy_loopinfo_to_se (&lse, &loop);
4675 gfc_copy_loopinfo_to_se (&rse, &loop);
4677 rse.ss = rss;
4678 gfc_mark_ss_chain_used (rss, 1);
4679 if (loop.temp_ss == NULL)
4681 lse.ss = lss;
4682 gfc_mark_ss_chain_used (lss, 1);
4684 else
4686 lse.ss = loop.temp_ss;
4687 gfc_mark_ss_chain_used (lss, 3);
4688 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4691 /* Start the scalarized loop body. */
4692 gfc_start_scalarized_body (&loop, &body);
4694 /* Translate the expression. */
4695 gfc_conv_expr (&rse, expr2);
4696 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4697 gfc_conv_tmp_array_ref (&lse);
4698 else
4699 gfc_conv_expr (&lse, expr1);
4701 /* Form the mask expression according to the mask. */
4702 index = count1;
4703 maskexpr = gfc_build_array_ref (mask, index, NULL);
4704 if (invert)
4705 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4706 TREE_TYPE (maskexpr), maskexpr);
4708 /* Use the scalar assignment as is. */
4709 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4710 false, loop.temp_ss == NULL);
4712 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4714 gfc_add_expr_to_block (&body, tmp);
4716 if (lss == gfc_ss_terminator)
4718 /* Increment count1. */
4719 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4720 count1, gfc_index_one_node);
4721 gfc_add_modify (&body, count1, tmp);
4723 /* Use the scalar assignment as is. */
4724 gfc_add_block_to_block (&block, &body);
4726 else
4728 gcc_assert (lse.ss == gfc_ss_terminator
4729 && rse.ss == gfc_ss_terminator);
4731 if (loop.temp_ss != NULL)
4733 /* Increment count1 before finish the main body of a scalarized
4734 expression. */
4735 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4736 gfc_array_index_type, count1, gfc_index_one_node);
4737 gfc_add_modify (&body, count1, tmp);
4738 gfc_trans_scalarized_loop_boundary (&loop, &body);
4740 /* We need to copy the temporary to the actual lhs. */
4741 gfc_init_se (&lse, NULL);
4742 gfc_init_se (&rse, NULL);
4743 gfc_copy_loopinfo_to_se (&lse, &loop);
4744 gfc_copy_loopinfo_to_se (&rse, &loop);
4746 rse.ss = loop.temp_ss;
4747 lse.ss = lss;
4749 gfc_conv_tmp_array_ref (&rse);
4750 gfc_conv_expr (&lse, expr1);
4752 gcc_assert (lse.ss == gfc_ss_terminator
4753 && rse.ss == gfc_ss_terminator);
4755 /* Form the mask expression according to the mask tree list. */
4756 index = count2;
4757 maskexpr = gfc_build_array_ref (mask, index, NULL);
4758 if (invert)
4759 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4760 TREE_TYPE (maskexpr), maskexpr);
4762 /* Use the scalar assignment as is. */
4763 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
4764 tmp = build3_v (COND_EXPR, maskexpr, tmp,
4765 build_empty_stmt (input_location));
4766 gfc_add_expr_to_block (&body, tmp);
4768 /* Increment count2. */
4769 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4770 gfc_array_index_type, count2,
4771 gfc_index_one_node);
4772 gfc_add_modify (&body, count2, tmp);
4774 else
4776 /* Increment count1. */
4777 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4778 gfc_array_index_type, count1,
4779 gfc_index_one_node);
4780 gfc_add_modify (&body, count1, tmp);
4783 /* Generate the copying loops. */
4784 gfc_trans_scalarizing_loops (&loop, &body);
4786 /* Wrap the whole thing up. */
4787 gfc_add_block_to_block (&block, &loop.pre);
4788 gfc_add_block_to_block (&block, &loop.post);
4789 gfc_cleanup_loop (&loop);
4792 return gfc_finish_block (&block);
4796 /* Translate the WHERE construct or statement.
4797 This function can be called iteratively to translate the nested WHERE
4798 construct or statement.
4799 MASK is the control mask. */
4801 static void
4802 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4803 forall_info * nested_forall_info, stmtblock_t * block)
4805 stmtblock_t inner_size_body;
4806 tree inner_size, size;
4807 gfc_ss *lss, *rss;
4808 tree mask_type;
4809 gfc_expr *expr1;
4810 gfc_expr *expr2;
4811 gfc_code *cblock;
4812 gfc_code *cnext;
4813 tree tmp;
4814 tree cond;
4815 tree count1, count2;
4816 bool need_cmask;
4817 bool need_pmask;
4818 int need_temp;
4819 tree pcmask = NULL_TREE;
4820 tree ppmask = NULL_TREE;
4821 tree cmask = NULL_TREE;
4822 tree pmask = NULL_TREE;
4823 gfc_actual_arglist *arg;
4825 /* the WHERE statement or the WHERE construct statement. */
4826 cblock = code->block;
4828 /* As the mask array can be very big, prefer compact boolean types. */
4829 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4831 /* Determine which temporary masks are needed. */
4832 if (!cblock->block)
4834 /* One clause: No ELSEWHEREs. */
4835 need_cmask = (cblock->next != 0);
4836 need_pmask = false;
4838 else if (cblock->block->block)
4840 /* Three or more clauses: Conditional ELSEWHEREs. */
4841 need_cmask = true;
4842 need_pmask = true;
4844 else if (cblock->next)
4846 /* Two clauses, the first non-empty. */
4847 need_cmask = true;
4848 need_pmask = (mask != NULL_TREE
4849 && cblock->block->next != 0);
4851 else if (!cblock->block->next)
4853 /* Two clauses, both empty. */
4854 need_cmask = false;
4855 need_pmask = false;
4857 /* Two clauses, the first empty, the second non-empty. */
4858 else if (mask)
4860 need_cmask = (cblock->block->expr1 != 0);
4861 need_pmask = true;
4863 else
4865 need_cmask = true;
4866 need_pmask = false;
4869 if (need_cmask || need_pmask)
4871 /* Calculate the size of temporary needed by the mask-expr. */
4872 gfc_init_block (&inner_size_body);
4873 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
4874 &inner_size_body, &lss, &rss);
4876 gfc_free_ss_chain (lss);
4877 gfc_free_ss_chain (rss);
4879 /* Calculate the total size of temporary needed. */
4880 size = compute_overall_iter_number (nested_forall_info, inner_size,
4881 &inner_size_body, block);
4883 /* Check whether the size is negative. */
4884 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, size,
4885 gfc_index_zero_node);
4886 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
4887 cond, gfc_index_zero_node, size);
4888 size = gfc_evaluate_now (size, block);
4890 /* Allocate temporary for WHERE mask if needed. */
4891 if (need_cmask)
4892 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4893 &pcmask);
4895 /* Allocate temporary for !mask if needed. */
4896 if (need_pmask)
4897 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4898 &ppmask);
4901 while (cblock)
4903 /* Each time around this loop, the where clause is conditional
4904 on the value of mask and invert, which are updated at the
4905 bottom of the loop. */
4907 /* Has mask-expr. */
4908 if (cblock->expr1)
4910 /* Ensure that the WHERE mask will be evaluated exactly once.
4911 If there are no statements in this WHERE/ELSEWHERE clause,
4912 then we don't need to update the control mask (cmask).
4913 If this is the last clause of the WHERE construct, then
4914 we don't need to update the pending control mask (pmask). */
4915 if (mask)
4916 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4917 mask, invert,
4918 cblock->next ? cmask : NULL_TREE,
4919 cblock->block ? pmask : NULL_TREE,
4920 mask_type, block);
4921 else
4922 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4923 NULL_TREE, false,
4924 (cblock->next || cblock->block)
4925 ? cmask : NULL_TREE,
4926 NULL_TREE, mask_type, block);
4928 invert = false;
4930 /* It's a final elsewhere-stmt. No mask-expr is present. */
4931 else
4932 cmask = mask;
4934 /* The body of this where clause are controlled by cmask with
4935 sense specified by invert. */
4937 /* Get the assignment statement of a WHERE statement, or the first
4938 statement in where-body-construct of a WHERE construct. */
4939 cnext = cblock->next;
4940 while (cnext)
4942 switch (cnext->op)
4944 /* WHERE assignment statement. */
4945 case EXEC_ASSIGN_CALL:
4947 arg = cnext->ext.actual;
4948 expr1 = expr2 = NULL;
4949 for (; arg; arg = arg->next)
4951 if (!arg->expr)
4952 continue;
4953 if (expr1 == NULL)
4954 expr1 = arg->expr;
4955 else
4956 expr2 = arg->expr;
4958 goto evaluate;
4960 case EXEC_ASSIGN:
4961 expr1 = cnext->expr1;
4962 expr2 = cnext->expr2;
4963 evaluate:
4964 if (nested_forall_info != NULL)
4966 need_temp = gfc_check_dependency (expr1, expr2, 0);
4967 if (need_temp && cnext->op != EXEC_ASSIGN_CALL)
4968 gfc_trans_assign_need_temp (expr1, expr2,
4969 cmask, invert,
4970 nested_forall_info, block);
4971 else
4973 /* Variables to control maskexpr. */
4974 count1 = gfc_create_var (gfc_array_index_type, "count1");
4975 count2 = gfc_create_var (gfc_array_index_type, "count2");
4976 gfc_add_modify (block, count1, gfc_index_zero_node);
4977 gfc_add_modify (block, count2, gfc_index_zero_node);
4979 tmp = gfc_trans_where_assign (expr1, expr2,
4980 cmask, invert,
4981 count1, count2,
4982 cnext);
4984 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4985 tmp, 1);
4986 gfc_add_expr_to_block (block, tmp);
4989 else
4991 /* Variables to control maskexpr. */
4992 count1 = gfc_create_var (gfc_array_index_type, "count1");
4993 count2 = gfc_create_var (gfc_array_index_type, "count2");
4994 gfc_add_modify (block, count1, gfc_index_zero_node);
4995 gfc_add_modify (block, count2, gfc_index_zero_node);
4997 tmp = gfc_trans_where_assign (expr1, expr2,
4998 cmask, invert,
4999 count1, count2,
5000 cnext);
5001 gfc_add_expr_to_block (block, tmp);
5004 break;
5006 /* WHERE or WHERE construct is part of a where-body-construct. */
5007 case EXEC_WHERE:
5008 gfc_trans_where_2 (cnext, cmask, invert,
5009 nested_forall_info, block);
5010 break;
5012 default:
5013 gcc_unreachable ();
5016 /* The next statement within the same where-body-construct. */
5017 cnext = cnext->next;
5019 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5020 cblock = cblock->block;
5021 if (mask == NULL_TREE)
5023 /* If we're the initial WHERE, we can simply invert the sense
5024 of the current mask to obtain the "mask" for the remaining
5025 ELSEWHEREs. */
5026 invert = true;
5027 mask = cmask;
5029 else
5031 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5032 invert = false;
5033 mask = pmask;
5037 /* If we allocated a pending mask array, deallocate it now. */
5038 if (ppmask)
5040 tmp = gfc_call_free (ppmask);
5041 gfc_add_expr_to_block (block, tmp);
5044 /* If we allocated a current mask array, deallocate it now. */
5045 if (pcmask)
5047 tmp = gfc_call_free (pcmask);
5048 gfc_add_expr_to_block (block, tmp);
5052 /* Translate a simple WHERE construct or statement without dependencies.
5053 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5054 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5055 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5057 static tree
5058 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5060 stmtblock_t block, body;
5061 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5062 tree tmp, cexpr, tstmt, estmt;
5063 gfc_ss *css, *tdss, *tsss;
5064 gfc_se cse, tdse, tsse, edse, esse;
5065 gfc_loopinfo loop;
5066 gfc_ss *edss = 0;
5067 gfc_ss *esss = 0;
5068 bool maybe_workshare = false;
5070 /* Allow the scalarizer to workshare simple where loops. */
5071 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5072 == OMPWS_WORKSHARE_FLAG)
5074 maybe_workshare = true;
5075 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5078 cond = cblock->expr1;
5079 tdst = cblock->next->expr1;
5080 tsrc = cblock->next->expr2;
5081 edst = eblock ? eblock->next->expr1 : NULL;
5082 esrc = eblock ? eblock->next->expr2 : NULL;
5084 gfc_start_block (&block);
5085 gfc_init_loopinfo (&loop);
5087 /* Handle the condition. */
5088 gfc_init_se (&cse, NULL);
5089 css = gfc_walk_expr (cond);
5090 gfc_add_ss_to_loop (&loop, css);
5092 /* Handle the then-clause. */
5093 gfc_init_se (&tdse, NULL);
5094 gfc_init_se (&tsse, NULL);
5095 tdss = gfc_walk_expr (tdst);
5096 tsss = gfc_walk_expr (tsrc);
5097 if (tsss == gfc_ss_terminator)
5099 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5100 tsss->info->where = 1;
5102 gfc_add_ss_to_loop (&loop, tdss);
5103 gfc_add_ss_to_loop (&loop, tsss);
5105 if (eblock)
5107 /* Handle the else clause. */
5108 gfc_init_se (&edse, NULL);
5109 gfc_init_se (&esse, NULL);
5110 edss = gfc_walk_expr (edst);
5111 esss = gfc_walk_expr (esrc);
5112 if (esss == gfc_ss_terminator)
5114 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5115 esss->info->where = 1;
5117 gfc_add_ss_to_loop (&loop, edss);
5118 gfc_add_ss_to_loop (&loop, esss);
5121 gfc_conv_ss_startstride (&loop);
5122 gfc_conv_loop_setup (&loop, &tdst->where);
5124 gfc_mark_ss_chain_used (css, 1);
5125 gfc_mark_ss_chain_used (tdss, 1);
5126 gfc_mark_ss_chain_used (tsss, 1);
5127 if (eblock)
5129 gfc_mark_ss_chain_used (edss, 1);
5130 gfc_mark_ss_chain_used (esss, 1);
5133 gfc_start_scalarized_body (&loop, &body);
5135 gfc_copy_loopinfo_to_se (&cse, &loop);
5136 gfc_copy_loopinfo_to_se (&tdse, &loop);
5137 gfc_copy_loopinfo_to_se (&tsse, &loop);
5138 cse.ss = css;
5139 tdse.ss = tdss;
5140 tsse.ss = tsss;
5141 if (eblock)
5143 gfc_copy_loopinfo_to_se (&edse, &loop);
5144 gfc_copy_loopinfo_to_se (&esse, &loop);
5145 edse.ss = edss;
5146 esse.ss = esss;
5149 gfc_conv_expr (&cse, cond);
5150 gfc_add_block_to_block (&body, &cse.pre);
5151 cexpr = cse.expr;
5153 gfc_conv_expr (&tsse, tsrc);
5154 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5155 gfc_conv_tmp_array_ref (&tdse);
5156 else
5157 gfc_conv_expr (&tdse, tdst);
5159 if (eblock)
5161 gfc_conv_expr (&esse, esrc);
5162 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5163 gfc_conv_tmp_array_ref (&edse);
5164 else
5165 gfc_conv_expr (&edse, edst);
5168 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5169 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5170 false, true)
5171 : build_empty_stmt (input_location);
5172 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5173 gfc_add_expr_to_block (&body, tmp);
5174 gfc_add_block_to_block (&body, &cse.post);
5176 if (maybe_workshare)
5177 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
5178 gfc_trans_scalarizing_loops (&loop, &body);
5179 gfc_add_block_to_block (&block, &loop.pre);
5180 gfc_add_block_to_block (&block, &loop.post);
5181 gfc_cleanup_loop (&loop);
5183 return gfc_finish_block (&block);
5186 /* As the WHERE or WHERE construct statement can be nested, we call
5187 gfc_trans_where_2 to do the translation, and pass the initial
5188 NULL values for both the control mask and the pending control mask. */
5190 tree
5191 gfc_trans_where (gfc_code * code)
5193 stmtblock_t block;
5194 gfc_code *cblock;
5195 gfc_code *eblock;
5197 cblock = code->block;
5198 if (cblock->next
5199 && cblock->next->op == EXEC_ASSIGN
5200 && !cblock->next->next)
5202 eblock = cblock->block;
5203 if (!eblock)
5205 /* A simple "WHERE (cond) x = y" statement or block is
5206 dependence free if cond is not dependent upon writing x,
5207 and the source y is unaffected by the destination x. */
5208 if (!gfc_check_dependency (cblock->next->expr1,
5209 cblock->expr1, 0)
5210 && !gfc_check_dependency (cblock->next->expr1,
5211 cblock->next->expr2, 0))
5212 return gfc_trans_where_3 (cblock, NULL);
5214 else if (!eblock->expr1
5215 && !eblock->block
5216 && eblock->next
5217 && eblock->next->op == EXEC_ASSIGN
5218 && !eblock->next->next)
5220 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5221 block is dependence free if cond is not dependent on writes
5222 to x1 and x2, y1 is not dependent on writes to x2, and y2
5223 is not dependent on writes to x1, and both y's are not
5224 dependent upon their own x's. In addition to this, the
5225 final two dependency checks below exclude all but the same
5226 array reference if the where and elswhere destinations
5227 are the same. In short, this is VERY conservative and this
5228 is needed because the two loops, required by the standard
5229 are coalesced in gfc_trans_where_3. */
5230 if (!gfc_check_dependency (cblock->next->expr1,
5231 cblock->expr1, 0)
5232 && !gfc_check_dependency (eblock->next->expr1,
5233 cblock->expr1, 0)
5234 && !gfc_check_dependency (cblock->next->expr1,
5235 eblock->next->expr2, 1)
5236 && !gfc_check_dependency (eblock->next->expr1,
5237 cblock->next->expr2, 1)
5238 && !gfc_check_dependency (cblock->next->expr1,
5239 cblock->next->expr2, 1)
5240 && !gfc_check_dependency (eblock->next->expr1,
5241 eblock->next->expr2, 1)
5242 && !gfc_check_dependency (cblock->next->expr1,
5243 eblock->next->expr1, 0)
5244 && !gfc_check_dependency (eblock->next->expr1,
5245 cblock->next->expr1, 0))
5246 return gfc_trans_where_3 (cblock, eblock);
5250 gfc_start_block (&block);
5252 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5254 return gfc_finish_block (&block);
5258 /* CYCLE a DO loop. The label decl has already been created by
5259 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5260 node at the head of the loop. We must mark the label as used. */
5262 tree
5263 gfc_trans_cycle (gfc_code * code)
5265 tree cycle_label;
5267 cycle_label = code->ext.which_construct->cycle_label;
5268 gcc_assert (cycle_label);
5270 TREE_USED (cycle_label) = 1;
5271 return build1_v (GOTO_EXPR, cycle_label);
5275 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5276 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5277 loop. */
5279 tree
5280 gfc_trans_exit (gfc_code * code)
5282 tree exit_label;
5284 exit_label = code->ext.which_construct->exit_label;
5285 gcc_assert (exit_label);
5287 TREE_USED (exit_label) = 1;
5288 return build1_v (GOTO_EXPR, exit_label);
5292 /* Translate the ALLOCATE statement. */
5294 tree
5295 gfc_trans_allocate (gfc_code * code)
5297 gfc_alloc *al;
5298 gfc_expr *expr, *e3rhs = NULL;
5299 gfc_se se, se_sz;
5300 tree tmp;
5301 tree parm;
5302 tree stat;
5303 tree errmsg;
5304 tree errlen;
5305 tree label_errmsg;
5306 tree label_finish;
5307 tree memsz;
5308 tree al_vptr, al_len;
5309 /* If an expr3 is present, then store the tree for accessing its
5310 _vptr, and _len components in the variables, respectively. The
5311 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5312 the trees may be the NULL_TREE indicating that this is not
5313 available for expr3's type. */
5314 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5315 /* Classify what expr3 stores. */
5316 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5317 stmtblock_t block;
5318 stmtblock_t post;
5319 tree nelems;
5320 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
5321 gfc_symtree *newsym = NULL;
5323 if (!code->ext.alloc.list)
5324 return NULL_TREE;
5326 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5327 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5328 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5329 e3_is = E3_UNSET;
5331 gfc_init_block (&block);
5332 gfc_init_block (&post);
5334 /* STAT= (and maybe ERRMSG=) is present. */
5335 if (code->expr1)
5337 /* STAT=. */
5338 tree gfc_int4_type_node = gfc_get_int_type (4);
5339 stat = gfc_create_var (gfc_int4_type_node, "stat");
5341 /* ERRMSG= only makes sense with STAT=. */
5342 if (code->expr2)
5344 gfc_init_se (&se, NULL);
5345 se.want_pointer = 1;
5346 gfc_conv_expr_lhs (&se, code->expr2);
5347 errmsg = se.expr;
5348 errlen = se.string_length;
5350 else
5352 errmsg = null_pointer_node;
5353 errlen = build_int_cst (gfc_charlen_type_node, 0);
5356 /* GOTO destinations. */
5357 label_errmsg = gfc_build_label_decl (NULL_TREE);
5358 label_finish = gfc_build_label_decl (NULL_TREE);
5359 TREE_USED (label_finish) = 0;
5362 /* When an expr3 is present evaluate it only once. The standards prevent a
5363 dependency of expr3 on the objects in the allocate list. An expr3 can
5364 be pre-evaluated in all cases. One just has to make sure, to use the
5365 correct way, i.e., to get the descriptor or to get a reference
5366 expression. */
5367 if (code->expr3)
5369 bool vtab_needed = false, temp_var_needed = false,
5370 is_coarray = gfc_is_coarray (code->expr3);
5372 /* Figure whether we need the vtab from expr3. */
5373 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5374 al = al->next)
5375 vtab_needed = (al->expr->ts.type == BT_CLASS);
5377 gfc_init_se (&se, NULL);
5378 /* When expr3 is a variable, i.e., a very simple expression,
5379 then convert it once here. */
5380 if (code->expr3->expr_type == EXPR_VARIABLE
5381 || code->expr3->expr_type == EXPR_ARRAY
5382 || code->expr3->expr_type == EXPR_CONSTANT)
5384 if (!code->expr3->mold
5385 || code->expr3->ts.type == BT_CHARACTER
5386 || vtab_needed
5387 || code->ext.alloc.arr_spec_from_expr3)
5389 /* Convert expr3 to a tree. For all "simple" expression just
5390 get the descriptor or the reference, respectively, depending
5391 on the rank of the expr. */
5392 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5393 gfc_conv_expr_descriptor (&se, code->expr3);
5394 else
5396 gfc_conv_expr_reference (&se, code->expr3);
5398 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5399 NOP_EXPR, which prevents gfortran from getting the vptr
5400 from the source=-expression. Remove the NOP_EXPR and go
5401 with the POINTER_PLUS_EXPR in this case. */
5402 if (code->expr3->ts.type == BT_CLASS
5403 && TREE_CODE (se.expr) == NOP_EXPR
5404 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5405 == POINTER_PLUS_EXPR
5406 || is_coarray))
5407 se.expr = TREE_OPERAND (se.expr, 0);
5409 /* Create a temp variable only for component refs to prevent
5410 having to go through the full deref-chain each time and to
5411 simplfy computation of array properties. */
5412 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5415 else
5417 /* In all other cases evaluate the expr3. */
5418 symbol_attribute attr;
5419 /* Get the descriptor for all arrays, that are not allocatable or
5420 pointer, because the latter are descriptors already.
5421 The exception are function calls returning a class object:
5422 The descriptor is stored in their results _data component, which
5423 is easier to access, when first a temporary variable for the
5424 result is created and the descriptor retrieved from there. */
5425 attr = gfc_expr_attr (code->expr3);
5426 if (code->expr3->rank != 0
5427 && ((!attr.allocatable && !attr.pointer)
5428 || (code->expr3->expr_type == EXPR_FUNCTION
5429 && code->expr3->ts.type != BT_CLASS)))
5430 gfc_conv_expr_descriptor (&se, code->expr3);
5431 else
5432 gfc_conv_expr_reference (&se, code->expr3);
5433 if (code->expr3->ts.type == BT_CLASS)
5434 gfc_conv_class_to_class (&se, code->expr3,
5435 code->expr3->ts,
5436 false, true,
5437 false, false);
5438 temp_var_needed = !VAR_P (se.expr);
5440 gfc_add_block_to_block (&block, &se.pre);
5441 gfc_add_block_to_block (&post, &se.post);
5442 /* Prevent aliasing, i.e., se.expr may be already a
5443 variable declaration. */
5444 if (se.expr != NULL_TREE && temp_var_needed)
5446 tree var, desc;
5447 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5448 se.expr
5449 : build_fold_indirect_ref_loc (input_location, se.expr);
5451 /* Get the array descriptor and prepare it to be assigned to the
5452 temporary variable var. For classes the array descriptor is
5453 in the _data component and the object goes into the
5454 GFC_DECL_SAVED_DESCRIPTOR. */
5455 if (code->expr3->ts.type == BT_CLASS
5456 && code->expr3->rank != 0)
5458 /* When an array_ref was in expr3, then the descriptor is the
5459 first operand. */
5460 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5462 desc = TREE_OPERAND (tmp, 0);
5464 else
5466 desc = tmp;
5467 tmp = gfc_class_data_get (tmp);
5469 e3_is = E3_DESC;
5471 else
5472 desc = !is_coarray ? se.expr
5473 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5474 /* We need a regular (non-UID) symbol here, therefore give a
5475 prefix. */
5476 var = gfc_create_var (TREE_TYPE (tmp), "source");
5477 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5479 gfc_allocate_lang_decl (var);
5480 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5482 gfc_add_modify_loc (input_location, &block, var, tmp);
5484 /* Deallocate any allocatable components after all the allocations
5485 and assignments of expr3 have been completed. */
5486 if (code->expr3->ts.type == BT_DERIVED
5487 && code->expr3->rank == 0
5488 && code->expr3->ts.u.derived->attr.alloc_comp)
5490 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5491 var, 0);
5492 gfc_add_expr_to_block (&post, tmp);
5495 expr3 = var;
5496 if (se.string_length)
5497 /* Evaluate it assuming that it also is complicated like expr3. */
5498 expr3_len = gfc_evaluate_now (se.string_length, &block);
5500 else
5502 expr3 = se.expr;
5503 expr3_len = se.string_length;
5505 /* Store what the expr3 is to be used for. */
5506 if (e3_is == E3_UNSET)
5507 e3_is = expr3 != NULL_TREE ?
5508 (code->ext.alloc.arr_spec_from_expr3 ?
5509 E3_DESC
5510 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
5511 : E3_UNSET;
5513 /* Figure how to get the _vtab entry. This also obtains the tree
5514 expression for accessing the _len component, because only
5515 unlimited polymorphic objects, which are a subcategory of class
5516 types, have a _len component. */
5517 if (code->expr3->ts.type == BT_CLASS)
5519 gfc_expr *rhs;
5520 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
5521 build_fold_indirect_ref (expr3): expr3;
5522 /* Polymorphic SOURCE: VPTR must be determined at run time.
5523 expr3 may be a temporary array declaration, therefore check for
5524 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5525 if (tmp != NULL_TREE
5526 && (e3_is == E3_DESC
5527 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
5528 && (VAR_P (tmp) || !code->expr3->ref))
5529 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
5530 tmp = gfc_class_vptr_get (expr3);
5531 else
5533 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5534 gfc_add_vptr_component (rhs);
5535 gfc_init_se (&se, NULL);
5536 se.want_pointer = 1;
5537 gfc_conv_expr (&se, rhs);
5538 tmp = se.expr;
5539 gfc_free_expr (rhs);
5541 /* Set the element size. */
5542 expr3_esize = gfc_vptr_size_get (tmp);
5543 if (vtab_needed)
5544 expr3_vptr = tmp;
5545 /* Initialize the ref to the _len component. */
5546 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5548 /* Same like for retrieving the _vptr. */
5549 if (expr3 != NULL_TREE && !code->expr3->ref)
5550 expr3_len = gfc_class_len_get (expr3);
5551 else
5553 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5554 gfc_add_len_component (rhs);
5555 gfc_init_se (&se, NULL);
5556 gfc_conv_expr (&se, rhs);
5557 expr3_len = se.expr;
5558 gfc_free_expr (rhs);
5562 else
5564 /* When the object to allocate is polymorphic type, then it
5565 needs its vtab set correctly, so deduce the required _vtab
5566 and _len from the source expression. */
5567 if (vtab_needed)
5569 /* VPTR is fixed at compile time. */
5570 gfc_symbol *vtab;
5572 vtab = gfc_find_vtab (&code->expr3->ts);
5573 gcc_assert (vtab);
5574 expr3_vptr = gfc_get_symbol_decl (vtab);
5575 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5576 expr3_vptr);
5578 /* _len component needs to be set, when ts is a character
5579 array. */
5580 if (expr3_len == NULL_TREE
5581 && code->expr3->ts.type == BT_CHARACTER)
5583 if (code->expr3->ts.u.cl
5584 && code->expr3->ts.u.cl->length)
5586 gfc_init_se (&se, NULL);
5587 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5588 gfc_add_block_to_block (&block, &se.pre);
5589 expr3_len = gfc_evaluate_now (se.expr, &block);
5591 gcc_assert (expr3_len);
5593 /* For character arrays only the kind's size is needed, because
5594 the array mem_size is _len * (elem_size = kind_size).
5595 For all other get the element size in the normal way. */
5596 if (code->expr3->ts.type == BT_CHARACTER)
5597 expr3_esize = TYPE_SIZE_UNIT (
5598 gfc_get_char_type (code->expr3->ts.kind));
5599 else
5600 expr3_esize = TYPE_SIZE_UNIT (
5601 gfc_typenode_for_spec (&code->expr3->ts));
5603 /* The routine gfc_trans_assignment () already implements all
5604 techniques needed. Unfortunately we may have a temporary
5605 variable for the source= expression here. When that is the
5606 case convert this variable into a temporary gfc_expr of type
5607 EXPR_VARIABLE and used it as rhs for the assignment. The
5608 advantage is, that we get scalarizer support for free,
5609 don't have to take care about scalar to array treatment and
5610 will benefit of every enhancements gfc_trans_assignment ()
5611 gets.
5612 No need to check whether e3_is is E3_UNSET, because that is
5613 done by expr3 != NULL_TREE.
5614 Exclude variables since the following block does not handle
5615 array sections. In any case, there is no harm in sending
5616 variables to gfc_trans_assignment because there is no
5617 evaluation of variables. */
5618 if (code->expr3->expr_type != EXPR_VARIABLE
5619 && e3_is != E3_MOLD && expr3 != NULL_TREE
5620 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
5622 /* Build a temporary symtree and symbol. Do not add it to
5623 the current namespace to prevent accidently modifying
5624 a colliding symbol's as. */
5625 newsym = XCNEW (gfc_symtree);
5626 /* The name of the symtree should be unique, because
5627 gfc_create_var () took care about generating the
5628 identifier. */
5629 newsym->name = gfc_get_string (IDENTIFIER_POINTER (
5630 DECL_NAME (expr3)));
5631 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
5632 /* The backend_decl is known. It is expr3, which is inserted
5633 here. */
5634 newsym->n.sym->backend_decl = expr3;
5635 e3rhs = gfc_get_expr ();
5636 e3rhs->ts = code->expr3->ts;
5637 e3rhs->rank = code->expr3->rank;
5638 e3rhs->symtree = newsym;
5639 /* Mark the symbol referenced or gfc_trans_assignment will
5640 bug. */
5641 newsym->n.sym->attr.referenced = 1;
5642 e3rhs->expr_type = EXPR_VARIABLE;
5643 e3rhs->where = code->expr3->where;
5644 /* Set the symbols type, upto it was BT_UNKNOWN. */
5645 newsym->n.sym->ts = e3rhs->ts;
5646 /* Check whether the expr3 is array valued. */
5647 if (e3rhs->rank)
5649 gfc_array_spec *arr;
5650 arr = gfc_get_array_spec ();
5651 arr->rank = e3rhs->rank;
5652 arr->type = AS_DEFERRED;
5653 /* Set the dimension and pointer attribute for arrays
5654 to be on the safe side. */
5655 newsym->n.sym->attr.dimension = 1;
5656 newsym->n.sym->attr.pointer = 1;
5657 newsym->n.sym->as = arr;
5658 gfc_add_full_array_ref (e3rhs, arr);
5660 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
5661 newsym->n.sym->attr.pointer = 1;
5662 /* The string length is known to. Set it for char arrays. */
5663 if (e3rhs->ts.type == BT_CHARACTER)
5664 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
5665 gfc_commit_symbol (newsym->n.sym);
5667 else
5668 e3rhs = gfc_copy_expr (code->expr3);
5670 gcc_assert (expr3_esize);
5671 expr3_esize = fold_convert (sizetype, expr3_esize);
5672 if (e3_is == E3_MOLD)
5674 /* The expr3 is no longer valid after this point. */
5675 expr3 = NULL_TREE;
5676 e3_is = E3_UNSET;
5679 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5681 /* Compute the explicit typespec given only once for all objects
5682 to allocate. */
5683 if (code->ext.alloc.ts.type != BT_CHARACTER)
5684 expr3_esize = TYPE_SIZE_UNIT (
5685 gfc_typenode_for_spec (&code->ext.alloc.ts));
5686 else
5688 gfc_expr *sz;
5689 gcc_assert (code->ext.alloc.ts.u.cl->length != NULL);
5690 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5691 gfc_init_se (&se_sz, NULL);
5692 gfc_conv_expr (&se_sz, sz);
5693 gfc_free_expr (sz);
5694 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5695 tmp = TYPE_SIZE_UNIT (tmp);
5696 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5697 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5698 TREE_TYPE (se_sz.expr),
5699 tmp, se_sz.expr);
5703 /* Loop over all objects to allocate. */
5704 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5706 expr = gfc_copy_expr (al->expr);
5707 /* UNLIMITED_POLY () needs the _data component to be set, when
5708 expr is a unlimited polymorphic object. But the _data component
5709 has not been set yet, so check the derived type's attr for the
5710 unlimited polymorphic flag to be safe. */
5711 upoly_expr = UNLIMITED_POLY (expr)
5712 || (expr->ts.type == BT_DERIVED
5713 && expr->ts.u.derived->attr.unlimited_polymorphic);
5714 gfc_init_se (&se, NULL);
5716 /* For class types prepare the expressions to ref the _vptr
5717 and the _len component. The latter for unlimited polymorphic
5718 types only. */
5719 if (expr->ts.type == BT_CLASS)
5721 gfc_expr *expr_ref_vptr, *expr_ref_len;
5722 gfc_add_data_component (expr);
5723 /* Prep the vptr handle. */
5724 expr_ref_vptr = gfc_copy_expr (al->expr);
5725 gfc_add_vptr_component (expr_ref_vptr);
5726 se.want_pointer = 1;
5727 gfc_conv_expr (&se, expr_ref_vptr);
5728 al_vptr = se.expr;
5729 se.want_pointer = 0;
5730 gfc_free_expr (expr_ref_vptr);
5731 /* Allocated unlimited polymorphic objects always have a _len
5732 component. */
5733 if (upoly_expr)
5735 expr_ref_len = gfc_copy_expr (al->expr);
5736 gfc_add_len_component (expr_ref_len);
5737 gfc_conv_expr (&se, expr_ref_len);
5738 al_len = se.expr;
5739 gfc_free_expr (expr_ref_len);
5741 else
5742 /* In a loop ensure that all loop variable dependent variables
5743 are initialized at the same spot in all execution paths. */
5744 al_len = NULL_TREE;
5746 else
5747 al_vptr = al_len = NULL_TREE;
5749 se.want_pointer = 1;
5750 se.descriptor_only = 1;
5752 gfc_conv_expr (&se, expr);
5753 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5754 /* se.string_length now stores the .string_length variable of expr
5755 needed to allocate character(len=:) arrays. */
5756 al_len = se.string_length;
5758 al_len_needs_set = al_len != NULL_TREE;
5759 /* When allocating an array one can not use much of the
5760 pre-evaluated expr3 expressions, because for most of them the
5761 scalarizer is needed which is not available in the pre-evaluation
5762 step. Therefore gfc_array_allocate () is responsible (and able)
5763 to handle the complete array allocation. Only the element size
5764 needs to be provided, which is done most of the time by the
5765 pre-evaluation step. */
5766 nelems = NULL_TREE;
5767 if (expr3_len && code->expr3->ts.type == BT_CHARACTER)
5768 /* When al is an array, then the element size for each element
5769 in the array is needed, which is the product of the len and
5770 esize for char arrays. */
5771 tmp = fold_build2_loc (input_location, MULT_EXPR,
5772 TREE_TYPE (expr3_esize), expr3_esize,
5773 fold_convert (TREE_TYPE (expr3_esize),
5774 expr3_len));
5775 else
5776 tmp = expr3_esize;
5777 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
5778 label_finish, tmp, &nelems,
5779 e3rhs ? e3rhs : code->expr3,
5780 e3_is == E3_DESC ? expr3 : NULL_TREE,
5781 code->expr3 != NULL && e3_is == E3_DESC
5782 && code->expr3->expr_type == EXPR_ARRAY))
5784 /* A scalar or derived type. First compute the size to
5785 allocate.
5787 expr3_len is set when expr3 is an unlimited polymorphic
5788 object or a deferred length string. */
5789 if (expr3_len != NULL_TREE)
5791 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
5792 tmp = fold_build2_loc (input_location, MULT_EXPR,
5793 TREE_TYPE (expr3_esize),
5794 expr3_esize, tmp);
5795 if (code->expr3->ts.type != BT_CLASS)
5796 /* expr3 is a deferred length string, i.e., we are
5797 done. */
5798 memsz = tmp;
5799 else
5801 /* For unlimited polymorphic enties build
5802 (len > 0) ? element_size * len : element_size
5803 to compute the number of bytes to allocate.
5804 This allows the allocation of unlimited polymorphic
5805 objects from an expr3 that is also unlimited
5806 polymorphic and stores a _len dependent object,
5807 e.g., a string. */
5808 memsz = fold_build2_loc (input_location, GT_EXPR,
5809 boolean_type_node, expr3_len,
5810 integer_zero_node);
5811 memsz = fold_build3_loc (input_location, COND_EXPR,
5812 TREE_TYPE (expr3_esize),
5813 memsz, tmp, expr3_esize);
5816 else if (expr3_esize != NULL_TREE)
5817 /* Any other object in expr3 just needs element size in
5818 bytes. */
5819 memsz = expr3_esize;
5820 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5821 || (upoly_expr
5822 && code->ext.alloc.ts.type == BT_CHARACTER))
5824 /* Allocating deferred length char arrays need the length
5825 to allocate in the alloc_type_spec. But also unlimited
5826 polymorphic objects may be allocated as char arrays.
5827 Both are handled here. */
5828 gfc_init_se (&se_sz, NULL);
5829 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5830 gfc_add_block_to_block (&se.pre, &se_sz.pre);
5831 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
5832 gfc_add_block_to_block (&se.pre, &se_sz.post);
5833 expr3_len = se_sz.expr;
5834 tmp_expr3_len_flag = true;
5835 tmp = TYPE_SIZE_UNIT (
5836 gfc_get_char_type (code->ext.alloc.ts.kind));
5837 memsz = fold_build2_loc (input_location, MULT_EXPR,
5838 TREE_TYPE (tmp),
5839 fold_convert (TREE_TYPE (tmp),
5840 expr3_len),
5841 tmp);
5843 else if (expr->ts.type == BT_CHARACTER)
5845 /* Compute the number of bytes needed to allocate a fixed
5846 length char array. */
5847 gcc_assert (se.string_length != NULL_TREE);
5848 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
5849 memsz = fold_build2_loc (input_location, MULT_EXPR,
5850 TREE_TYPE (tmp), tmp,
5851 fold_convert (TREE_TYPE (tmp),
5852 se.string_length));
5854 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5855 /* Handle all types, where the alloc_type_spec is set. */
5856 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
5857 else
5858 /* Handle size computation of the type declared to alloc. */
5859 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
5861 /* Allocate - for non-pointers with re-alloc checking. */
5862 if (gfc_expr_attr (expr).allocatable)
5863 gfc_allocate_allocatable (&se.pre, se.expr, memsz, NULL_TREE,
5864 stat, errmsg, errlen, label_finish,
5865 expr);
5866 else
5867 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
5869 if (al->expr->ts.type == BT_DERIVED
5870 && expr->ts.u.derived->attr.alloc_comp)
5872 tmp = build_fold_indirect_ref_loc (input_location, se.expr);
5873 tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, tmp, 0);
5874 gfc_add_expr_to_block (&se.pre, tmp);
5877 else
5879 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
5880 && expr3_len != NULL_TREE)
5882 /* Arrays need to have a _len set before the array
5883 descriptor is filled. */
5884 gfc_add_modify (&block, al_len,
5885 fold_convert (TREE_TYPE (al_len), expr3_len));
5886 /* Prevent setting the length twice. */
5887 al_len_needs_set = false;
5889 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
5890 && code->ext.alloc.ts.u.cl->length)
5892 /* Cover the cases where a string length is explicitly
5893 specified by a type spec for deferred length character
5894 arrays or unlimited polymorphic objects without a
5895 source= or mold= expression. */
5896 gfc_init_se (&se_sz, NULL);
5897 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5898 gfc_add_modify (&block, al_len,
5899 fold_convert (TREE_TYPE (al_len),
5900 se_sz.expr));
5901 al_len_needs_set = false;
5905 gfc_add_block_to_block (&block, &se.pre);
5907 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
5908 if (code->expr1)
5910 tmp = build1_v (GOTO_EXPR, label_errmsg);
5911 parm = fold_build2_loc (input_location, NE_EXPR,
5912 boolean_type_node, stat,
5913 build_int_cst (TREE_TYPE (stat), 0));
5914 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5915 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
5916 tmp, build_empty_stmt (input_location));
5917 gfc_add_expr_to_block (&block, tmp);
5920 /* Set the vptr. */
5921 if (al_vptr != NULL_TREE)
5923 if (expr3_vptr != NULL_TREE)
5924 /* The vtab is already known, so just assign it. */
5925 gfc_add_modify (&block, al_vptr,
5926 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
5927 else
5929 /* VPTR is fixed at compile time. */
5930 gfc_symbol *vtab;
5931 gfc_typespec *ts;
5933 if (code->expr3)
5934 /* Although expr3 is pre-evaluated above, it may happen,
5935 that for arrays or in mold= cases the pre-evaluation
5936 was not successful. In these rare cases take the vtab
5937 from the typespec of expr3 here. */
5938 ts = &code->expr3->ts;
5939 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
5940 /* The alloc_type_spec gives the type to allocate or the
5941 al is unlimited polymorphic, which enforces the use of
5942 an alloc_type_spec that is not necessarily a BT_DERIVED. */
5943 ts = &code->ext.alloc.ts;
5944 else
5945 /* Prepare for setting the vtab as declared. */
5946 ts = &expr->ts;
5948 vtab = gfc_find_vtab (ts);
5949 gcc_assert (vtab);
5950 tmp = gfc_build_addr_expr (NULL_TREE,
5951 gfc_get_symbol_decl (vtab));
5952 gfc_add_modify (&block, al_vptr,
5953 fold_convert (TREE_TYPE (al_vptr), tmp));
5957 /* Add assignment for string length. */
5958 if (al_len != NULL_TREE && al_len_needs_set)
5960 if (expr3_len != NULL_TREE)
5962 gfc_add_modify (&block, al_len,
5963 fold_convert (TREE_TYPE (al_len),
5964 expr3_len));
5965 /* When tmp_expr3_len_flag is set, then expr3_len is
5966 abused to carry the length information from the
5967 alloc_type. Clear it to prevent setting incorrect len
5968 information in future loop iterations. */
5969 if (tmp_expr3_len_flag)
5970 /* No need to reset tmp_expr3_len_flag, because the
5971 presence of an expr3 can not change within in the
5972 loop. */
5973 expr3_len = NULL_TREE;
5975 else if (code->ext.alloc.ts.type == BT_CHARACTER
5976 && code->ext.alloc.ts.u.cl->length)
5978 /* Cover the cases where a string length is explicitly
5979 specified by a type spec for deferred length character
5980 arrays or unlimited polymorphic objects without a
5981 source= or mold= expression. */
5982 gfc_init_se (&se_sz, NULL);
5983 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5984 gfc_add_modify (&block, al_len,
5985 fold_convert (TREE_TYPE (al_len),
5986 se_sz.expr));
5988 else
5989 /* No length information needed, because type to allocate
5990 has no length. Set _len to 0. */
5991 gfc_add_modify (&block, al_len,
5992 fold_convert (TREE_TYPE (al_len),
5993 integer_zero_node));
5995 if (code->expr3 && !code->expr3->mold)
5997 /* Initialization via SOURCE block (or static default initializer).
5998 Classes need some special handling, so catch them first. */
5999 if (expr3 != NULL_TREE
6000 && TREE_CODE (expr3) != POINTER_PLUS_EXPR
6001 && code->expr3->ts.type == BT_CLASS
6002 && (expr->ts.type == BT_CLASS
6003 || expr->ts.type == BT_DERIVED))
6005 /* copy_class_to_class can be used for class arrays, too.
6006 It just needs to be ensured, that the decl_saved_descriptor
6007 has a way to get to the vptr. */
6008 tree to;
6009 to = VAR_P (se.expr) ? se.expr : TREE_OPERAND (se.expr, 0);
6010 tmp = gfc_copy_class_to_class (expr3, to,
6011 nelems, upoly_expr);
6013 else if (al->expr->ts.type == BT_CLASS)
6015 gfc_actual_arglist *actual, *last_arg;
6016 gfc_expr *ppc;
6017 gfc_code *ppc_code;
6018 gfc_ref *ref, *dataref;
6019 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6021 /* Do a polymorphic deep copy. */
6022 actual = gfc_get_actual_arglist ();
6023 actual->expr = gfc_copy_expr (rhs);
6024 if (rhs->ts.type == BT_CLASS)
6025 gfc_add_data_component (actual->expr);
6026 last_arg = actual->next = gfc_get_actual_arglist ();
6027 last_arg->expr = gfc_copy_expr (al->expr);
6028 last_arg->expr->ts.type = BT_CLASS;
6029 gfc_add_data_component (last_arg->expr);
6031 dataref = NULL;
6032 /* Make sure we go up through the reference chain to
6033 the _data reference, where the arrayspec is found. */
6034 for (ref = last_arg->expr->ref; ref; ref = ref->next)
6035 if (ref->type == REF_COMPONENT
6036 && strcmp (ref->u.c.component->name, "_data") == 0)
6037 dataref = ref;
6039 if (dataref && dataref->u.c.component->as)
6041 gfc_array_spec *as = dataref->u.c.component->as;
6042 gfc_free_ref_list (dataref->next);
6043 dataref->next = NULL;
6044 gfc_add_full_array_ref (last_arg->expr, as);
6045 gfc_resolve_expr (last_arg->expr);
6046 gcc_assert (last_arg->expr->ts.type == BT_CLASS
6047 || last_arg->expr->ts.type == BT_DERIVED);
6048 last_arg->expr->ts.type = BT_CLASS;
6050 if (rhs->ts.type == BT_CLASS)
6052 if (rhs->ref)
6053 ppc = gfc_find_and_cut_at_last_class_ref (rhs);
6054 else
6055 ppc = gfc_copy_expr (rhs);
6056 gfc_add_vptr_component (ppc);
6058 else
6059 ppc = gfc_lval_expr_from_sym (gfc_find_vtab (&rhs->ts));
6060 gfc_add_component_ref (ppc, "_copy");
6062 ppc_code = gfc_get_code (EXEC_CALL);
6063 ppc_code->resolved_sym = ppc->symtree->n.sym;
6064 ppc_code->loc = al->expr->where;
6065 /* Although '_copy' is set to be elemental in class.c, it is
6066 not staying that way. Find out why, sometime.... */
6067 ppc_code->resolved_sym->attr.elemental = 1;
6068 ppc_code->ext.actual = actual;
6069 ppc_code->expr1 = ppc;
6070 /* Since '_copy' is elemental, the scalarizer will take care
6071 of arrays in gfc_trans_call. */
6072 tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
6073 /* We need to add the
6074 if (al_len > 0)
6075 al_vptr->copy (expr3_data, al_data, expr3_len, al_len);
6076 else
6077 al_vptr->copy (expr3_data, al_data);
6078 block, because al is unlimited polymorphic or a deferred
6079 length char array, whose copy routine needs the array lengths
6080 as third and fourth arguments. */
6081 if (al_len && UNLIMITED_POLY (code->expr3))
6083 tree stdcopy, extcopy;
6084 /* Add al%_len. */
6085 last_arg->next = gfc_get_actual_arglist ();
6086 last_arg = last_arg->next;
6087 last_arg->expr = gfc_find_and_cut_at_last_class_ref (
6088 al->expr);
6089 gfc_add_len_component (last_arg->expr);
6090 /* Add expr3's length. */
6091 last_arg->next = gfc_get_actual_arglist ();
6092 last_arg = last_arg->next;
6093 if (code->expr3->ts.type == BT_CLASS)
6095 last_arg->expr =
6096 gfc_find_and_cut_at_last_class_ref (code->expr3);
6097 gfc_add_len_component (last_arg->expr);
6099 else if (code->expr3->ts.type == BT_CHARACTER)
6100 last_arg->expr =
6101 gfc_copy_expr (code->expr3->ts.u.cl->length);
6102 else
6103 gcc_unreachable ();
6105 stdcopy = tmp;
6106 extcopy = gfc_trans_call (ppc_code, true, NULL, NULL, false);
6108 tmp = fold_build2_loc (input_location, GT_EXPR,
6109 boolean_type_node, expr3_len,
6110 integer_zero_node);
6111 tmp = fold_build3_loc (input_location, COND_EXPR,
6112 void_type_node, tmp, extcopy, stdcopy);
6114 gfc_free_statements (ppc_code);
6115 if (rhs != e3rhs)
6116 gfc_free_expr (rhs);
6118 else
6120 /* Switch off automatic reallocation since we have just
6121 done the ALLOCATE. */
6122 int realloc_lhs = flag_realloc_lhs;
6123 flag_realloc_lhs = 0;
6124 tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
6125 e3rhs, false, false);
6126 flag_realloc_lhs = realloc_lhs;
6128 gfc_add_expr_to_block (&block, tmp);
6130 else if (code->expr3 && code->expr3->mold
6131 && code->expr3->ts.type == BT_CLASS)
6133 /* Since the _vptr has already been assigned to the allocate
6134 object, we can use gfc_copy_class_to_class in its
6135 initialization mode. */
6136 tmp = TREE_OPERAND (se.expr, 0);
6137 tmp = gfc_copy_class_to_class (NULL_TREE, tmp, nelems,
6138 upoly_expr);
6139 gfc_add_expr_to_block (&block, tmp);
6142 gfc_free_expr (expr);
6143 } // for-loop
6145 if (e3rhs)
6147 if (newsym)
6149 gfc_free_symbol (newsym->n.sym);
6150 XDELETE (newsym);
6152 gfc_free_expr (e3rhs);
6154 /* STAT. */
6155 if (code->expr1)
6157 tmp = build1_v (LABEL_EXPR, label_errmsg);
6158 gfc_add_expr_to_block (&block, tmp);
6161 /* ERRMSG - only useful if STAT is present. */
6162 if (code->expr1 && code->expr2)
6164 const char *msg = "Attempt to allocate an allocated object";
6165 tree slen, dlen, errmsg_str;
6166 stmtblock_t errmsg_block;
6168 gfc_init_block (&errmsg_block);
6170 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6171 gfc_add_modify (&errmsg_block, errmsg_str,
6172 gfc_build_addr_expr (pchar_type_node,
6173 gfc_build_localized_cstring_const (msg)));
6175 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6176 dlen = gfc_get_expr_charlen (code->expr2);
6177 slen = fold_build2_loc (input_location, MIN_EXPR,
6178 TREE_TYPE (slen), dlen, slen);
6180 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6181 code->expr2->ts.kind,
6182 slen, errmsg_str,
6183 gfc_default_character_kind);
6184 dlen = gfc_finish_block (&errmsg_block);
6186 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6187 stat, build_int_cst (TREE_TYPE (stat), 0));
6189 tmp = build3_v (COND_EXPR, tmp,
6190 dlen, build_empty_stmt (input_location));
6192 gfc_add_expr_to_block (&block, tmp);
6195 /* STAT block. */
6196 if (code->expr1)
6198 if (TREE_USED (label_finish))
6200 tmp = build1_v (LABEL_EXPR, label_finish);
6201 gfc_add_expr_to_block (&block, tmp);
6204 gfc_init_se (&se, NULL);
6205 gfc_conv_expr_lhs (&se, code->expr1);
6206 tmp = convert (TREE_TYPE (se.expr), stat);
6207 gfc_add_modify (&block, se.expr, tmp);
6210 gfc_add_block_to_block (&block, &se.post);
6211 gfc_add_block_to_block (&block, &post);
6213 return gfc_finish_block (&block);
6217 /* Translate a DEALLOCATE statement. */
6219 tree
6220 gfc_trans_deallocate (gfc_code *code)
6222 gfc_se se;
6223 gfc_alloc *al;
6224 tree apstat, pstat, stat, errmsg, errlen, tmp;
6225 tree label_finish, label_errmsg;
6226 stmtblock_t block;
6228 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6229 label_finish = label_errmsg = NULL_TREE;
6231 gfc_start_block (&block);
6233 /* Count the number of failed deallocations. If deallocate() was
6234 called with STAT= , then set STAT to the count. If deallocate
6235 was called with ERRMSG, then set ERRMG to a string. */
6236 if (code->expr1)
6238 tree gfc_int4_type_node = gfc_get_int_type (4);
6240 stat = gfc_create_var (gfc_int4_type_node, "stat");
6241 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6243 /* GOTO destinations. */
6244 label_errmsg = gfc_build_label_decl (NULL_TREE);
6245 label_finish = gfc_build_label_decl (NULL_TREE);
6246 TREE_USED (label_finish) = 0;
6249 /* Set ERRMSG - only needed if STAT is available. */
6250 if (code->expr1 && code->expr2)
6252 gfc_init_se (&se, NULL);
6253 se.want_pointer = 1;
6254 gfc_conv_expr_lhs (&se, code->expr2);
6255 errmsg = se.expr;
6256 errlen = se.string_length;
6259 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6261 gfc_expr *expr = gfc_copy_expr (al->expr);
6262 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6264 if (expr->ts.type == BT_CLASS)
6265 gfc_add_data_component (expr);
6267 gfc_init_se (&se, NULL);
6268 gfc_start_block (&se.pre);
6270 se.want_pointer = 1;
6271 se.descriptor_only = 1;
6272 gfc_conv_expr (&se, expr);
6274 if (expr->rank || gfc_is_coarray (expr))
6276 gfc_ref *ref;
6278 if (gfc_bt_struct (expr->ts.type) && expr->ts.u.derived->attr.alloc_comp
6279 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6281 gfc_ref *last = NULL;
6283 for (ref = expr->ref; ref; ref = ref->next)
6284 if (ref->type == REF_COMPONENT)
6285 last = ref;
6287 /* Do not deallocate the components of a derived type
6288 ultimate pointer component. */
6289 if (!(last && last->u.c.component->attr.pointer)
6290 && !(!last && expr->symtree->n.sym->attr.pointer))
6292 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr,
6293 expr->rank);
6294 gfc_add_expr_to_block (&se.pre, tmp);
6298 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6300 tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen,
6301 label_finish, expr);
6302 gfc_add_expr_to_block (&se.pre, tmp);
6304 else if (TREE_CODE (se.expr) == COMPONENT_REF
6305 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6306 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6307 == RECORD_TYPE)
6309 /* class.c(finalize_component) generates these, when a
6310 finalizable entity has a non-allocatable derived type array
6311 component, which has allocatable components. Obtain the
6312 derived type of the array and deallocate the allocatable
6313 components. */
6314 for (ref = expr->ref; ref; ref = ref->next)
6316 if (ref->u.c.component->attr.dimension
6317 && ref->u.c.component->ts.type == BT_DERIVED)
6318 break;
6321 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6322 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6323 NULL))
6325 tmp = gfc_deallocate_alloc_comp
6326 (ref->u.c.component->ts.u.derived,
6327 se.expr, expr->rank);
6328 gfc_add_expr_to_block (&se.pre, tmp);
6332 if (al->expr->ts.type == BT_CLASS)
6334 gfc_reset_vptr (&se.pre, al->expr);
6335 if (UNLIMITED_POLY (al->expr)
6336 || (al->expr->ts.type == BT_DERIVED
6337 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6338 /* Clear _len, too. */
6339 gfc_reset_len (&se.pre, al->expr);
6342 else
6344 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, false,
6345 al->expr, al->expr->ts);
6346 gfc_add_expr_to_block (&se.pre, tmp);
6348 /* Set to zero after deallocation. */
6349 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6350 se.expr,
6351 build_int_cst (TREE_TYPE (se.expr), 0));
6352 gfc_add_expr_to_block (&se.pre, tmp);
6354 if (al->expr->ts.type == BT_CLASS)
6356 gfc_reset_vptr (&se.pre, al->expr);
6357 if (UNLIMITED_POLY (al->expr)
6358 || (al->expr->ts.type == BT_DERIVED
6359 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6360 /* Clear _len, too. */
6361 gfc_reset_len (&se.pre, al->expr);
6365 if (code->expr1)
6367 tree cond;
6369 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6370 build_int_cst (TREE_TYPE (stat), 0));
6371 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6372 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6373 build1_v (GOTO_EXPR, label_errmsg),
6374 build_empty_stmt (input_location));
6375 gfc_add_expr_to_block (&se.pre, tmp);
6378 tmp = gfc_finish_block (&se.pre);
6379 gfc_add_expr_to_block (&block, tmp);
6380 gfc_free_expr (expr);
6383 if (code->expr1)
6385 tmp = build1_v (LABEL_EXPR, label_errmsg);
6386 gfc_add_expr_to_block (&block, tmp);
6389 /* Set ERRMSG - only needed if STAT is available. */
6390 if (code->expr1 && code->expr2)
6392 const char *msg = "Attempt to deallocate an unallocated object";
6393 stmtblock_t errmsg_block;
6394 tree errmsg_str, slen, dlen, cond;
6396 gfc_init_block (&errmsg_block);
6398 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6399 gfc_add_modify (&errmsg_block, errmsg_str,
6400 gfc_build_addr_expr (pchar_type_node,
6401 gfc_build_localized_cstring_const (msg)));
6402 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6403 dlen = gfc_get_expr_charlen (code->expr2);
6405 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6406 slen, errmsg_str, gfc_default_character_kind);
6407 tmp = gfc_finish_block (&errmsg_block);
6409 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6410 build_int_cst (TREE_TYPE (stat), 0));
6411 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6412 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6413 build_empty_stmt (input_location));
6415 gfc_add_expr_to_block (&block, tmp);
6418 if (code->expr1 && TREE_USED (label_finish))
6420 tmp = build1_v (LABEL_EXPR, label_finish);
6421 gfc_add_expr_to_block (&block, tmp);
6424 /* Set STAT. */
6425 if (code->expr1)
6427 gfc_init_se (&se, NULL);
6428 gfc_conv_expr_lhs (&se, code->expr1);
6429 tmp = convert (TREE_TYPE (se.expr), stat);
6430 gfc_add_modify (&block, se.expr, tmp);
6433 return gfc_finish_block (&block);
6436 #include "gt-fortran-trans-stmt.h"