* ggc.h (empty_string): Delete.
[official-gcc.git] / gcc / fortran / trans-stmt.c
bloba1e1dff72e0a02b4797e0efd7870e1bd03958f35
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "options.h"
27 #include "tree.h"
28 #include "gfortran.h"
29 #include "trans.h"
30 #include "stringpool.h"
31 #include "fold-const.h"
32 #include "trans-stmt.h"
33 #include "trans-types.h"
34 #include "trans-array.h"
35 #include "trans-const.h"
36 #include "dependency.h"
38 typedef struct iter_info
40 tree var;
41 tree start;
42 tree end;
43 tree step;
44 struct iter_info *next;
46 iter_info;
48 typedef struct forall_info
50 iter_info *this_loop;
51 tree mask;
52 tree maskindex;
53 int nvar;
54 tree size;
55 struct forall_info *prev_nest;
56 bool do_concurrent;
58 forall_info;
60 static void gfc_trans_where_2 (gfc_code *, tree, bool,
61 forall_info *, stmtblock_t *);
63 /* Translate a F95 label number to a LABEL_EXPR. */
65 tree
66 gfc_trans_label_here (gfc_code * code)
68 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
72 /* Given a variable expression which has been ASSIGNed to, find the decl
73 containing the auxiliary variables. For variables in common blocks this
74 is a field_decl. */
76 void
77 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
79 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
80 gfc_conv_expr (se, expr);
81 /* Deals with variable in common block. Get the field declaration. */
82 if (TREE_CODE (se->expr) == COMPONENT_REF)
83 se->expr = TREE_OPERAND (se->expr, 1);
84 /* Deals with dummy argument. Get the parameter declaration. */
85 else if (TREE_CODE (se->expr) == INDIRECT_REF)
86 se->expr = TREE_OPERAND (se->expr, 0);
89 /* Translate a label assignment statement. */
91 tree
92 gfc_trans_label_assign (gfc_code * code)
94 tree label_tree;
95 gfc_se se;
96 tree len;
97 tree addr;
98 tree len_tree;
99 int label_len;
101 /* Start a new block. */
102 gfc_init_se (&se, NULL);
103 gfc_start_block (&se.pre);
104 gfc_conv_label_variable (&se, code->expr1);
106 len = GFC_DECL_STRING_LEN (se.expr);
107 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
109 label_tree = gfc_get_label_decl (code->label1);
111 if (code->label1->defined == ST_LABEL_TARGET
112 || code->label1->defined == ST_LABEL_DO_TARGET)
114 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
115 len_tree = integer_minus_one_node;
117 else
119 gfc_expr *format = code->label1->format;
121 label_len = format->value.character.length;
122 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
123 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
124 format->value.character.string);
125 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
128 gfc_add_modify (&se.pre, len, len_tree);
129 gfc_add_modify (&se.pre, addr, label_tree);
131 return gfc_finish_block (&se.pre);
134 /* Translate a GOTO statement. */
136 tree
137 gfc_trans_goto (gfc_code * code)
139 locus loc = code->loc;
140 tree assigned_goto;
141 tree target;
142 tree tmp;
143 gfc_se se;
145 if (code->label1 != NULL)
146 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
148 /* ASSIGNED GOTO. */
149 gfc_init_se (&se, NULL);
150 gfc_start_block (&se.pre);
151 gfc_conv_label_variable (&se, code->expr1);
152 tmp = GFC_DECL_STRING_LEN (se.expr);
153 tmp = fold_build2_loc (input_location, NE_EXPR, 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 if (code->expr1)
456 gfc_conv_loop_setup (&loop, &code->expr1->where);
457 else
458 gfc_conv_loop_setup (&loop, &code->loc);
460 gfc_mark_ss_chain_used (ss, 1);
462 /* Convert the arguments, checking for dependencies. */
463 gfc_copy_loopinfo_to_se (&loopse, &loop);
464 loopse.ss = ss;
466 /* For operator assignment, do dependency checking. */
467 if (dependency_check)
468 check_variable = ELEM_CHECK_VARIABLE;
469 else
470 check_variable = ELEM_DONT_CHECK_VARIABLE;
472 gfc_init_se (&depse, NULL);
473 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
474 code->ext.actual, check_variable);
476 gfc_add_block_to_block (&loop.pre, &depse.pre);
477 gfc_add_block_to_block (&loop.post, &depse.post);
479 /* Generate the loop body. */
480 gfc_start_scalarized_body (&loop, &body);
481 gfc_init_block (&block);
483 if (mask && count1)
485 /* Form the mask expression according to the mask. */
486 index = count1;
487 maskexpr = gfc_build_array_ref (mask, index, NULL);
488 if (invert)
489 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
490 TREE_TYPE (maskexpr), maskexpr);
493 /* Add the subroutine call to the block. */
494 gfc_conv_procedure_call (&loopse, code->resolved_sym,
495 code->ext.actual, code->expr1,
496 NULL);
498 if (mask && count1)
500 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
501 build_empty_stmt (input_location));
502 gfc_add_expr_to_block (&loopse.pre, tmp);
503 tmp = fold_build2_loc (input_location, PLUS_EXPR,
504 gfc_array_index_type,
505 count1, gfc_index_one_node);
506 gfc_add_modify (&loopse.pre, count1, tmp);
508 else
509 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
511 gfc_add_block_to_block (&block, &loopse.pre);
512 gfc_add_block_to_block (&block, &loopse.post);
514 /* Finish up the loop block and the loop. */
515 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
516 gfc_trans_scalarizing_loops (&loop, &body);
517 gfc_add_block_to_block (&se.pre, &loop.pre);
518 gfc_add_block_to_block (&se.pre, &loop.post);
519 gfc_add_block_to_block (&se.pre, &se.post);
520 gfc_cleanup_loop (&loop);
523 return gfc_finish_block (&se.pre);
527 /* Translate the RETURN statement. */
529 tree
530 gfc_trans_return (gfc_code * code)
532 if (code->expr1)
534 gfc_se se;
535 tree tmp;
536 tree result;
538 /* If code->expr is not NULL, this return statement must appear
539 in a subroutine and current_fake_result_decl has already
540 been generated. */
542 result = gfc_get_fake_result_decl (NULL, 0);
543 if (!result)
545 gfc_warning (0,
546 "An alternate return at %L without a * dummy argument",
547 &code->expr1->where);
548 return gfc_generate_return ();
551 /* Start a new block for this statement. */
552 gfc_init_se (&se, NULL);
553 gfc_start_block (&se.pre);
555 gfc_conv_expr (&se, code->expr1);
557 /* Note that the actually returned expression is a simple value and
558 does not depend on any pointers or such; thus we can clean-up with
559 se.post before returning. */
560 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
561 result, fold_convert (TREE_TYPE (result),
562 se.expr));
563 gfc_add_expr_to_block (&se.pre, tmp);
564 gfc_add_block_to_block (&se.pre, &se.post);
566 tmp = gfc_generate_return ();
567 gfc_add_expr_to_block (&se.pre, tmp);
568 return gfc_finish_block (&se.pre);
571 return gfc_generate_return ();
575 /* Translate the PAUSE statement. We have to translate this statement
576 to a runtime library call. */
578 tree
579 gfc_trans_pause (gfc_code * code)
581 tree gfc_int4_type_node = gfc_get_int_type (4);
582 gfc_se se;
583 tree tmp;
585 /* Start a new block for this statement. */
586 gfc_init_se (&se, NULL);
587 gfc_start_block (&se.pre);
590 if (code->expr1 == NULL)
592 tmp = build_int_cst (gfc_int4_type_node, 0);
593 tmp = build_call_expr_loc (input_location,
594 gfor_fndecl_pause_string, 2,
595 build_int_cst (pchar_type_node, 0), tmp);
597 else if (code->expr1->ts.type == BT_INTEGER)
599 gfc_conv_expr (&se, code->expr1);
600 tmp = build_call_expr_loc (input_location,
601 gfor_fndecl_pause_numeric, 1,
602 fold_convert (gfc_int4_type_node, se.expr));
604 else
606 gfc_conv_expr_reference (&se, code->expr1);
607 tmp = build_call_expr_loc (input_location,
608 gfor_fndecl_pause_string, 2,
609 se.expr, se.string_length);
612 gfc_add_expr_to_block (&se.pre, tmp);
614 gfc_add_block_to_block (&se.pre, &se.post);
616 return gfc_finish_block (&se.pre);
620 /* Translate the STOP statement. We have to translate this statement
621 to a runtime library call. */
623 tree
624 gfc_trans_stop (gfc_code *code, bool error_stop)
626 tree gfc_int4_type_node = gfc_get_int_type (4);
627 gfc_se se;
628 tree tmp;
630 /* Start a new block for this statement. */
631 gfc_init_se (&se, NULL);
632 gfc_start_block (&se.pre);
634 if (code->expr1 == NULL)
636 tmp = build_int_cst (gfc_int4_type_node, 0);
637 tmp = build_call_expr_loc (input_location,
638 error_stop
639 ? (flag_coarray == GFC_FCOARRAY_LIB
640 ? gfor_fndecl_caf_error_stop_str
641 : gfor_fndecl_error_stop_string)
642 : (flag_coarray == GFC_FCOARRAY_LIB
643 ? gfor_fndecl_caf_stop_str
644 : gfor_fndecl_stop_string),
645 2, build_int_cst (pchar_type_node, 0), tmp);
647 else if (code->expr1->ts.type == BT_INTEGER)
649 gfc_conv_expr (&se, code->expr1);
650 tmp = build_call_expr_loc (input_location,
651 error_stop
652 ? (flag_coarray == GFC_FCOARRAY_LIB
653 ? gfor_fndecl_caf_error_stop
654 : gfor_fndecl_error_stop_numeric)
655 : (flag_coarray == GFC_FCOARRAY_LIB
656 ? gfor_fndecl_caf_stop_numeric
657 : gfor_fndecl_stop_numeric), 1,
658 fold_convert (gfc_int4_type_node, se.expr));
660 else
662 gfc_conv_expr_reference (&se, code->expr1);
663 tmp = build_call_expr_loc (input_location,
664 error_stop
665 ? (flag_coarray == GFC_FCOARRAY_LIB
666 ? gfor_fndecl_caf_error_stop_str
667 : gfor_fndecl_error_stop_string)
668 : (flag_coarray == GFC_FCOARRAY_LIB
669 ? gfor_fndecl_caf_stop_str
670 : gfor_fndecl_stop_string),
671 2, se.expr, se.string_length);
674 gfc_add_expr_to_block (&se.pre, tmp);
676 gfc_add_block_to_block (&se.pre, &se.post);
678 return gfc_finish_block (&se.pre);
681 /* Translate the FAIL IMAGE statement. */
683 tree
684 gfc_trans_fail_image (gfc_code *code ATTRIBUTE_UNUSED)
686 if (flag_coarray == GFC_FCOARRAY_LIB)
687 return build_call_expr_loc (input_location,
688 gfor_fndecl_caf_fail_image, 1,
689 build_int_cst (pchar_type_node, 0));
690 else
692 const char *name = gfc_get_string (PREFIX ("exit_i%d"), 4);
693 gfc_symbol *exsym = gfc_get_intrinsic_sub_symbol (name);
694 tree tmp = gfc_get_symbol_decl (exsym);
695 return build_call_expr_loc (input_location, tmp, 1, integer_zero_node);
700 tree
701 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
703 gfc_se se, argse;
704 tree stat = NULL_TREE, stat2 = NULL_TREE;
705 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
707 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
708 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
709 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
710 return NULL_TREE;
712 if (code->expr2)
714 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
715 gfc_init_se (&argse, NULL);
716 gfc_conv_expr_val (&argse, code->expr2);
717 stat = argse.expr;
719 else if (flag_coarray == GFC_FCOARRAY_LIB)
720 stat = null_pointer_node;
722 if (code->expr4)
724 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
725 gfc_init_se (&argse, NULL);
726 gfc_conv_expr_val (&argse, code->expr4);
727 lock_acquired = argse.expr;
729 else if (flag_coarray == GFC_FCOARRAY_LIB)
730 lock_acquired = null_pointer_node;
732 gfc_start_block (&se.pre);
733 if (flag_coarray == GFC_FCOARRAY_LIB)
735 tree tmp, token, image_index, errmsg, errmsg_len;
736 tree index = size_zero_node;
737 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
739 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
740 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
741 != INTMOD_ISO_FORTRAN_ENV
742 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
743 != ISOFORTRAN_LOCK_TYPE)
745 gfc_error ("Sorry, the lock component of derived type at %L is not "
746 "yet supported", &code->expr1->where);
747 return NULL_TREE;
750 gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
751 code->expr1);
753 if (gfc_is_coindexed (code->expr1))
754 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
755 else
756 image_index = integer_zero_node;
758 /* For arrays, obtain the array index. */
759 if (gfc_expr_attr (code->expr1).dimension)
761 tree desc, tmp, extent, lbound, ubound;
762 gfc_array_ref *ar, ar2;
763 int i;
765 /* TODO: Extend this, once DT components are supported. */
766 ar = &code->expr1->ref->u.ar;
767 ar2 = *ar;
768 memset (ar, '\0', sizeof (*ar));
769 ar->as = ar2.as;
770 ar->type = AR_FULL;
772 gfc_init_se (&argse, NULL);
773 argse.descriptor_only = 1;
774 gfc_conv_expr_descriptor (&argse, code->expr1);
775 gfc_add_block_to_block (&se.pre, &argse.pre);
776 desc = argse.expr;
777 *ar = ar2;
779 extent = integer_one_node;
780 for (i = 0; i < ar->dimen; i++)
782 gfc_init_se (&argse, NULL);
783 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
784 gfc_add_block_to_block (&argse.pre, &argse.pre);
785 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
786 tmp = fold_build2_loc (input_location, MINUS_EXPR,
787 integer_type_node, argse.expr,
788 fold_convert(integer_type_node, lbound));
789 tmp = fold_build2_loc (input_location, MULT_EXPR,
790 integer_type_node, extent, tmp);
791 index = fold_build2_loc (input_location, PLUS_EXPR,
792 integer_type_node, index, tmp);
793 if (i < ar->dimen - 1)
795 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
796 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
797 tmp = fold_convert (integer_type_node, tmp);
798 extent = fold_build2_loc (input_location, MULT_EXPR,
799 integer_type_node, extent, tmp);
804 /* errmsg. */
805 if (code->expr3)
807 gfc_init_se (&argse, NULL);
808 argse.want_pointer = 1;
809 gfc_conv_expr (&argse, code->expr3);
810 gfc_add_block_to_block (&se.pre, &argse.pre);
811 errmsg = argse.expr;
812 errmsg_len = fold_convert (integer_type_node, argse.string_length);
814 else
816 errmsg = null_pointer_node;
817 errmsg_len = integer_zero_node;
820 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
822 stat2 = stat;
823 stat = gfc_create_var (integer_type_node, "stat");
826 if (lock_acquired != null_pointer_node
827 && TREE_TYPE (lock_acquired) != integer_type_node)
829 lock_acquired2 = lock_acquired;
830 lock_acquired = gfc_create_var (integer_type_node, "acquired");
833 if (op == EXEC_LOCK)
834 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
835 token, index, image_index,
836 lock_acquired != null_pointer_node
837 ? gfc_build_addr_expr (NULL, lock_acquired)
838 : lock_acquired,
839 stat != null_pointer_node
840 ? gfc_build_addr_expr (NULL, stat) : stat,
841 errmsg, errmsg_len);
842 else
843 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
844 token, index, image_index,
845 stat != null_pointer_node
846 ? gfc_build_addr_expr (NULL, stat) : stat,
847 errmsg, errmsg_len);
848 gfc_add_expr_to_block (&se.pre, tmp);
850 /* It guarantees memory consistency within the same segment */
851 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
852 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
853 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
854 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
855 ASM_VOLATILE_P (tmp) = 1;
857 gfc_add_expr_to_block (&se.pre, tmp);
859 if (stat2 != NULL_TREE)
860 gfc_add_modify (&se.pre, stat2,
861 fold_convert (TREE_TYPE (stat2), stat));
863 if (lock_acquired2 != NULL_TREE)
864 gfc_add_modify (&se.pre, lock_acquired2,
865 fold_convert (TREE_TYPE (lock_acquired2),
866 lock_acquired));
868 return gfc_finish_block (&se.pre);
871 if (stat != NULL_TREE)
872 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
874 if (lock_acquired != NULL_TREE)
875 gfc_add_modify (&se.pre, lock_acquired,
876 fold_convert (TREE_TYPE (lock_acquired),
877 boolean_true_node));
879 return gfc_finish_block (&se.pre);
882 tree
883 gfc_trans_event_post_wait (gfc_code *code, gfc_exec_op op)
885 gfc_se se, argse;
886 tree stat = NULL_TREE, stat2 = NULL_TREE;
887 tree until_count = NULL_TREE;
889 if (code->expr2)
891 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
892 gfc_init_se (&argse, NULL);
893 gfc_conv_expr_val (&argse, code->expr2);
894 stat = argse.expr;
896 else if (flag_coarray == GFC_FCOARRAY_LIB)
897 stat = null_pointer_node;
899 if (code->expr4)
901 gfc_init_se (&argse, NULL);
902 gfc_conv_expr_val (&argse, code->expr4);
903 until_count = fold_convert (integer_type_node, argse.expr);
905 else
906 until_count = integer_one_node;
908 if (flag_coarray != GFC_FCOARRAY_LIB)
910 gfc_start_block (&se.pre);
911 gfc_init_se (&argse, NULL);
912 gfc_conv_expr_val (&argse, code->expr1);
914 if (op == EXEC_EVENT_POST)
915 gfc_add_modify (&se.pre, argse.expr,
916 fold_build2_loc (input_location, PLUS_EXPR,
917 TREE_TYPE (argse.expr), argse.expr,
918 build_int_cst (TREE_TYPE (argse.expr), 1)));
919 else
920 gfc_add_modify (&se.pre, argse.expr,
921 fold_build2_loc (input_location, MINUS_EXPR,
922 TREE_TYPE (argse.expr), argse.expr,
923 fold_convert (TREE_TYPE (argse.expr),
924 until_count)));
925 if (stat != NULL_TREE)
926 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
928 return gfc_finish_block (&se.pre);
931 gfc_start_block (&se.pre);
932 tree tmp, token, image_index, errmsg, errmsg_len;
933 tree index = size_zero_node;
934 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
936 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
937 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
938 != INTMOD_ISO_FORTRAN_ENV
939 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
940 != ISOFORTRAN_EVENT_TYPE)
942 gfc_error ("Sorry, the event component of derived type at %L is not "
943 "yet supported", &code->expr1->where);
944 return NULL_TREE;
947 gfc_init_se (&argse, NULL);
948 gfc_get_caf_token_offset (&argse, &token, NULL, caf_decl, NULL_TREE,
949 code->expr1);
950 gfc_add_block_to_block (&se.pre, &argse.pre);
952 if (gfc_is_coindexed (code->expr1))
953 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
954 else
955 image_index = integer_zero_node;
957 /* For arrays, obtain the array index. */
958 if (gfc_expr_attr (code->expr1).dimension)
960 tree desc, tmp, extent, lbound, ubound;
961 gfc_array_ref *ar, ar2;
962 int i;
964 /* TODO: Extend this, once DT components are supported. */
965 ar = &code->expr1->ref->u.ar;
966 ar2 = *ar;
967 memset (ar, '\0', sizeof (*ar));
968 ar->as = ar2.as;
969 ar->type = AR_FULL;
971 gfc_init_se (&argse, NULL);
972 argse.descriptor_only = 1;
973 gfc_conv_expr_descriptor (&argse, code->expr1);
974 gfc_add_block_to_block (&se.pre, &argse.pre);
975 desc = argse.expr;
976 *ar = ar2;
978 extent = integer_one_node;
979 for (i = 0; i < ar->dimen; i++)
981 gfc_init_se (&argse, NULL);
982 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
983 gfc_add_block_to_block (&argse.pre, &argse.pre);
984 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
985 tmp = fold_build2_loc (input_location, MINUS_EXPR,
986 integer_type_node, argse.expr,
987 fold_convert(integer_type_node, lbound));
988 tmp = fold_build2_loc (input_location, MULT_EXPR,
989 integer_type_node, extent, tmp);
990 index = fold_build2_loc (input_location, PLUS_EXPR,
991 integer_type_node, index, tmp);
992 if (i < ar->dimen - 1)
994 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
995 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
996 tmp = fold_convert (integer_type_node, tmp);
997 extent = fold_build2_loc (input_location, MULT_EXPR,
998 integer_type_node, extent, tmp);
1003 /* errmsg. */
1004 if (code->expr3)
1006 gfc_init_se (&argse, NULL);
1007 argse.want_pointer = 1;
1008 gfc_conv_expr (&argse, code->expr3);
1009 gfc_add_block_to_block (&se.pre, &argse.pre);
1010 errmsg = argse.expr;
1011 errmsg_len = fold_convert (integer_type_node, argse.string_length);
1013 else
1015 errmsg = null_pointer_node;
1016 errmsg_len = integer_zero_node;
1019 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
1021 stat2 = stat;
1022 stat = gfc_create_var (integer_type_node, "stat");
1025 if (op == EXEC_EVENT_POST)
1026 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_post, 6,
1027 token, index, image_index,
1028 stat != null_pointer_node
1029 ? gfc_build_addr_expr (NULL, stat) : stat,
1030 errmsg, errmsg_len);
1031 else
1032 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_wait, 6,
1033 token, index, until_count,
1034 stat != null_pointer_node
1035 ? gfc_build_addr_expr (NULL, stat) : stat,
1036 errmsg, errmsg_len);
1037 gfc_add_expr_to_block (&se.pre, tmp);
1039 /* It guarantees memory consistency within the same segment */
1040 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1041 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1042 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1043 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1044 ASM_VOLATILE_P (tmp) = 1;
1045 gfc_add_expr_to_block (&se.pre, tmp);
1047 if (stat2 != NULL_TREE)
1048 gfc_add_modify (&se.pre, stat2, fold_convert (TREE_TYPE (stat2), stat));
1050 return gfc_finish_block (&se.pre);
1053 tree
1054 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
1056 gfc_se se, argse;
1057 tree tmp;
1058 tree images = NULL_TREE, stat = NULL_TREE,
1059 errmsg = NULL_TREE, errmsglen = NULL_TREE;
1061 /* Short cut: For single images without bound checking or without STAT=,
1062 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
1063 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1064 && flag_coarray != GFC_FCOARRAY_LIB)
1065 return NULL_TREE;
1067 gfc_init_se (&se, NULL);
1068 gfc_start_block (&se.pre);
1070 if (code->expr1 && code->expr1->rank == 0)
1072 gfc_init_se (&argse, NULL);
1073 gfc_conv_expr_val (&argse, code->expr1);
1074 images = argse.expr;
1077 if (code->expr2)
1079 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
1080 gfc_init_se (&argse, NULL);
1081 gfc_conv_expr_val (&argse, code->expr2);
1082 stat = argse.expr;
1084 else
1085 stat = null_pointer_node;
1087 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
1089 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
1090 gfc_init_se (&argse, NULL);
1091 argse.want_pointer = 1;
1092 gfc_conv_expr (&argse, code->expr3);
1093 gfc_conv_string_parameter (&argse);
1094 errmsg = gfc_build_addr_expr (NULL, argse.expr);
1095 errmsglen = argse.string_length;
1097 else if (flag_coarray == GFC_FCOARRAY_LIB)
1099 errmsg = null_pointer_node;
1100 errmsglen = build_int_cst (integer_type_node, 0);
1103 /* Check SYNC IMAGES(imageset) for valid image index.
1104 FIXME: Add a check for image-set arrays. */
1105 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1106 && code->expr1->rank == 0)
1108 tree cond;
1109 if (flag_coarray != GFC_FCOARRAY_LIB)
1110 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1111 images, build_int_cst (TREE_TYPE (images), 1));
1112 else
1114 tree cond2;
1115 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
1116 2, integer_zero_node,
1117 build_int_cst (integer_type_node, -1));
1118 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1119 images, tmp);
1120 cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1121 images,
1122 build_int_cst (TREE_TYPE (images), 1));
1123 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1124 boolean_type_node, cond, cond2);
1126 gfc_trans_runtime_check (true, false, cond, &se.pre,
1127 &code->expr1->where, "Invalid image number "
1128 "%d in SYNC IMAGES",
1129 fold_convert (integer_type_node, images));
1132 /* Per F2008, 8.5.1, a SYNC MEMORY is implied by calling the
1133 image control statements SYNC IMAGES and SYNC ALL. */
1134 if (flag_coarray == GFC_FCOARRAY_LIB)
1136 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1137 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1138 gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
1139 tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
1140 ASM_VOLATILE_P (tmp) = 1;
1141 gfc_add_expr_to_block (&se.pre, tmp);
1144 if (flag_coarray != GFC_FCOARRAY_LIB)
1146 /* Set STAT to zero. */
1147 if (code->expr2)
1148 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
1150 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
1152 /* SYNC ALL => stat == null_pointer_node
1153 SYNC ALL(stat=s) => stat has an integer type
1155 If "stat" has the wrong integer type, use a temp variable of
1156 the right type and later cast the result back into "stat". */
1157 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1159 if (TREE_TYPE (stat) == integer_type_node)
1160 stat = gfc_build_addr_expr (NULL, stat);
1162 if(type == EXEC_SYNC_MEMORY)
1163 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
1164 3, stat, errmsg, errmsglen);
1165 else
1166 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1167 3, stat, errmsg, errmsglen);
1169 gfc_add_expr_to_block (&se.pre, tmp);
1171 else
1173 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1175 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
1176 3, gfc_build_addr_expr (NULL, tmp_stat),
1177 errmsg, errmsglen);
1178 gfc_add_expr_to_block (&se.pre, tmp);
1180 gfc_add_modify (&se.pre, stat,
1181 fold_convert (TREE_TYPE (stat), tmp_stat));
1184 else
1186 tree len;
1188 gcc_assert (type == EXEC_SYNC_IMAGES);
1190 if (!code->expr1)
1192 len = build_int_cst (integer_type_node, -1);
1193 images = null_pointer_node;
1195 else if (code->expr1->rank == 0)
1197 len = build_int_cst (integer_type_node, 1);
1198 images = gfc_build_addr_expr (NULL_TREE, images);
1200 else
1202 /* FIXME. */
1203 if (code->expr1->ts.kind != gfc_c_int_kind)
1204 gfc_fatal_error ("Sorry, only support for integer kind %d "
1205 "implemented for image-set at %L",
1206 gfc_c_int_kind, &code->expr1->where);
1208 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
1209 images = se.expr;
1211 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1212 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1213 tmp = gfc_get_element_type (tmp);
1215 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1216 TREE_TYPE (len), len,
1217 fold_convert (TREE_TYPE (len),
1218 TYPE_SIZE_UNIT (tmp)));
1219 len = fold_convert (integer_type_node, len);
1222 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1223 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1225 If "stat" has the wrong integer type, use a temp variable of
1226 the right type and later cast the result back into "stat". */
1227 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1229 if (TREE_TYPE (stat) == integer_type_node)
1230 stat = gfc_build_addr_expr (NULL, stat);
1232 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1233 5, fold_convert (integer_type_node, len),
1234 images, stat, errmsg, errmsglen);
1235 gfc_add_expr_to_block (&se.pre, tmp);
1237 else
1239 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1241 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1242 5, fold_convert (integer_type_node, len),
1243 images, gfc_build_addr_expr (NULL, tmp_stat),
1244 errmsg, errmsglen);
1245 gfc_add_expr_to_block (&se.pre, tmp);
1247 gfc_add_modify (&se.pre, stat,
1248 fold_convert (TREE_TYPE (stat), tmp_stat));
1252 return gfc_finish_block (&se.pre);
1256 /* Generate GENERIC for the IF construct. This function also deals with
1257 the simple IF statement, because the front end translates the IF
1258 statement into an IF construct.
1260 We translate:
1262 IF (cond) THEN
1263 then_clause
1264 ELSEIF (cond2)
1265 elseif_clause
1266 ELSE
1267 else_clause
1268 ENDIF
1270 into:
1272 pre_cond_s;
1273 if (cond_s)
1275 then_clause;
1277 else
1279 pre_cond_s
1280 if (cond_s)
1282 elseif_clause
1284 else
1286 else_clause;
1290 where COND_S is the simplified version of the predicate. PRE_COND_S
1291 are the pre side-effects produced by the translation of the
1292 conditional.
1293 We need to build the chain recursively otherwise we run into
1294 problems with folding incomplete statements. */
1296 static tree
1297 gfc_trans_if_1 (gfc_code * code)
1299 gfc_se if_se;
1300 tree stmt, elsestmt;
1301 locus saved_loc;
1302 location_t loc;
1304 /* Check for an unconditional ELSE clause. */
1305 if (!code->expr1)
1306 return gfc_trans_code (code->next);
1308 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1309 gfc_init_se (&if_se, NULL);
1310 gfc_start_block (&if_se.pre);
1312 /* Calculate the IF condition expression. */
1313 if (code->expr1->where.lb)
1315 gfc_save_backend_locus (&saved_loc);
1316 gfc_set_backend_locus (&code->expr1->where);
1319 gfc_conv_expr_val (&if_se, code->expr1);
1321 if (code->expr1->where.lb)
1322 gfc_restore_backend_locus (&saved_loc);
1324 /* Translate the THEN clause. */
1325 stmt = gfc_trans_code (code->next);
1327 /* Translate the ELSE clause. */
1328 if (code->block)
1329 elsestmt = gfc_trans_if_1 (code->block);
1330 else
1331 elsestmt = build_empty_stmt (input_location);
1333 /* Build the condition expression and add it to the condition block. */
1334 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1335 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1336 elsestmt);
1338 gfc_add_expr_to_block (&if_se.pre, stmt);
1340 /* Finish off this statement. */
1341 return gfc_finish_block (&if_se.pre);
1344 tree
1345 gfc_trans_if (gfc_code * code)
1347 stmtblock_t body;
1348 tree exit_label;
1350 /* Create exit label so it is available for trans'ing the body code. */
1351 exit_label = gfc_build_label_decl (NULL_TREE);
1352 code->exit_label = exit_label;
1354 /* Translate the actual code in code->block. */
1355 gfc_init_block (&body);
1356 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1358 /* Add exit label. */
1359 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1361 return gfc_finish_block (&body);
1365 /* Translate an arithmetic IF expression.
1367 IF (cond) label1, label2, label3 translates to
1369 if (cond <= 0)
1371 if (cond < 0)
1372 goto label1;
1373 else // cond == 0
1374 goto label2;
1376 else // cond > 0
1377 goto label3;
1379 An optimized version can be generated in case of equal labels.
1380 E.g., if label1 is equal to label2, we can translate it to
1382 if (cond <= 0)
1383 goto label1;
1384 else
1385 goto label3;
1388 tree
1389 gfc_trans_arithmetic_if (gfc_code * code)
1391 gfc_se se;
1392 tree tmp;
1393 tree branch1;
1394 tree branch2;
1395 tree zero;
1397 /* Start a new block. */
1398 gfc_init_se (&se, NULL);
1399 gfc_start_block (&se.pre);
1401 /* Pre-evaluate COND. */
1402 gfc_conv_expr_val (&se, code->expr1);
1403 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1405 /* Build something to compare with. */
1406 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1408 if (code->label1->value != code->label2->value)
1410 /* If (cond < 0) take branch1 else take branch2.
1411 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1412 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1413 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1415 if (code->label1->value != code->label3->value)
1416 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1417 se.expr, zero);
1418 else
1419 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1420 se.expr, zero);
1422 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1423 tmp, branch1, branch2);
1425 else
1426 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1428 if (code->label1->value != code->label3->value
1429 && code->label2->value != code->label3->value)
1431 /* if (cond <= 0) take branch1 else take branch2. */
1432 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1433 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1434 se.expr, zero);
1435 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1436 tmp, branch1, branch2);
1439 /* Append the COND_EXPR to the evaluation of COND, and return. */
1440 gfc_add_expr_to_block (&se.pre, branch1);
1441 return gfc_finish_block (&se.pre);
1445 /* Translate a CRITICAL block. */
1446 tree
1447 gfc_trans_critical (gfc_code *code)
1449 stmtblock_t block;
1450 tree tmp, token = NULL_TREE;
1452 gfc_start_block (&block);
1454 if (flag_coarray == GFC_FCOARRAY_LIB)
1456 token = gfc_get_symbol_decl (code->resolved_sym);
1457 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1458 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1459 token, integer_zero_node, integer_one_node,
1460 null_pointer_node, null_pointer_node,
1461 null_pointer_node, integer_zero_node);
1462 gfc_add_expr_to_block (&block, tmp);
1464 /* It guarantees memory consistency within the same segment */
1465 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1466 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1467 gfc_build_string_const (1, ""),
1468 NULL_TREE, NULL_TREE,
1469 tree_cons (NULL_TREE, tmp, NULL_TREE),
1470 NULL_TREE);
1471 ASM_VOLATILE_P (tmp) = 1;
1473 gfc_add_expr_to_block (&block, tmp);
1476 tmp = gfc_trans_code (code->block->next);
1477 gfc_add_expr_to_block (&block, tmp);
1479 if (flag_coarray == GFC_FCOARRAY_LIB)
1481 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1482 token, integer_zero_node, integer_one_node,
1483 null_pointer_node, null_pointer_node,
1484 integer_zero_node);
1485 gfc_add_expr_to_block (&block, tmp);
1487 /* It guarantees memory consistency within the same segment */
1488 tmp = gfc_build_string_const (strlen ("memory")+1, "memory"),
1489 tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
1490 gfc_build_string_const (1, ""),
1491 NULL_TREE, NULL_TREE,
1492 tree_cons (NULL_TREE, tmp, NULL_TREE),
1493 NULL_TREE);
1494 ASM_VOLATILE_P (tmp) = 1;
1496 gfc_add_expr_to_block (&block, tmp);
1499 return gfc_finish_block (&block);
1503 /* Return true, when the class has a _len component. */
1505 static bool
1506 class_has_len_component (gfc_symbol *sym)
1508 gfc_component *comp = sym->ts.u.derived->components;
1509 while (comp)
1511 if (strcmp (comp->name, "_len") == 0)
1512 return true;
1513 comp = comp->next;
1515 return false;
1519 /* Do proper initialization for ASSOCIATE names. */
1521 static void
1522 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1524 gfc_expr *e;
1525 tree tmp;
1526 bool class_target;
1527 bool unlimited;
1528 tree desc;
1529 tree offset;
1530 tree dim;
1531 int n;
1532 tree charlen;
1533 bool need_len_assign;
1535 gcc_assert (sym->assoc);
1536 e = sym->assoc->target;
1538 class_target = (e->expr_type == EXPR_VARIABLE)
1539 && (gfc_is_class_scalar_expr (e)
1540 || gfc_is_class_array_ref (e, NULL));
1542 unlimited = UNLIMITED_POLY (e);
1544 /* Assignments to the string length need to be generated, when
1545 ( sym is a char array or
1546 sym has a _len component)
1547 and the associated expression is unlimited polymorphic, which is
1548 not (yet) correctly in 'unlimited', because for an already associated
1549 BT_DERIVED the u-poly flag is not set, i.e.,
1550 __tmp_CHARACTER_0_1 => w => arg
1551 ^ generated temp ^ from code, the w does not have the u-poly
1552 flag set, where UNLIMITED_POLY(e) expects it. */
1553 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1554 && e->ts.u.derived->attr.unlimited_polymorphic))
1555 && (sym->ts.type == BT_CHARACTER
1556 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1557 && class_has_len_component (sym))));
1558 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1559 to array temporary) for arrays with either unknown shape or if associating
1560 to a variable. */
1561 if (sym->attr.dimension && !class_target
1562 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1564 gfc_se se;
1565 tree desc;
1566 bool cst_array_ctor;
1568 desc = sym->backend_decl;
1569 cst_array_ctor = e->expr_type == EXPR_ARRAY
1570 && gfc_constant_array_constructor_p (e->value.constructor);
1572 /* If association is to an expression, evaluate it and create temporary.
1573 Otherwise, get descriptor of target for pointer assignment. */
1574 gfc_init_se (&se, NULL);
1575 if (sym->assoc->variable || cst_array_ctor)
1577 se.direct_byref = 1;
1578 se.use_offset = 1;
1579 se.expr = desc;
1582 gfc_conv_expr_descriptor (&se, e);
1584 /* If we didn't already do the pointer assignment, set associate-name
1585 descriptor to the one generated for the temporary. */
1586 if (!sym->assoc->variable && !cst_array_ctor)
1588 int dim;
1590 gfc_add_modify (&se.pre, desc, se.expr);
1592 /* The generated descriptor has lower bound zero (as array
1593 temporary), shift bounds so we get lower bounds of 1. */
1594 for (dim = 0; dim < e->rank; ++dim)
1595 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1596 dim, gfc_index_one_node);
1599 /* If this is a subreference array pointer associate name use the
1600 associate variable element size for the value of 'span'. */
1601 if (sym->attr.subref_array_pointer)
1603 gcc_assert (e->expr_type == EXPR_VARIABLE);
1604 tmp = e->symtree->n.sym->ts.type == BT_CLASS
1605 ? gfc_class_data_get (e->symtree->n.sym->backend_decl)
1606 : e->symtree->n.sym->backend_decl;
1607 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1608 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1609 gfc_add_modify (&se.pre, GFC_DECL_SPAN(desc), tmp);
1612 /* Done, register stuff as init / cleanup code. */
1613 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1614 gfc_finish_block (&se.post));
1617 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1618 arrays to be assigned directly. */
1619 else if (class_target && sym->attr.dimension
1620 && (sym->ts.type == BT_DERIVED || unlimited))
1622 gfc_se se;
1624 gfc_init_se (&se, NULL);
1625 se.descriptor_only = 1;
1626 /* In a select type the (temporary) associate variable shall point to
1627 a standard fortran array (lower bound == 1), but conv_expr ()
1628 just maps to the input array in the class object, whose lbound may
1629 be arbitrary. conv_expr_descriptor solves this by inserting a
1630 temporary array descriptor. */
1631 gfc_conv_expr_descriptor (&se, e);
1633 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1634 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1635 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1637 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1639 if (INDIRECT_REF_P (se.expr))
1640 tmp = TREE_OPERAND (se.expr, 0);
1641 else
1642 tmp = se.expr;
1644 gfc_add_modify (&se.pre, sym->backend_decl,
1645 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1647 else
1648 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1650 if (unlimited)
1652 /* Recover the dtype, which has been overwritten by the
1653 assignment from an unlimited polymorphic object. */
1654 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1655 gfc_add_modify (&se.pre, tmp,
1656 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1659 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1660 gfc_finish_block (&se.post));
1663 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1664 else if (gfc_is_associate_pointer (sym))
1666 gfc_se se;
1668 gcc_assert (!sym->attr.dimension);
1670 gfc_init_se (&se, NULL);
1672 /* Class associate-names come this way because they are
1673 unconditionally associate pointers and the symbol is scalar. */
1674 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1676 tree target_expr;
1677 /* For a class array we need a descriptor for the selector. */
1678 gfc_conv_expr_descriptor (&se, e);
1679 /* Needed to get/set the _len component below. */
1680 target_expr = se.expr;
1682 /* Obtain a temporary class container for the result. */
1683 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1684 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1686 /* Set the offset. */
1687 desc = gfc_class_data_get (se.expr);
1688 offset = gfc_index_zero_node;
1689 for (n = 0; n < e->rank; n++)
1691 dim = gfc_rank_cst[n];
1692 tmp = fold_build2_loc (input_location, MULT_EXPR,
1693 gfc_array_index_type,
1694 gfc_conv_descriptor_stride_get (desc, dim),
1695 gfc_conv_descriptor_lbound_get (desc, dim));
1696 offset = fold_build2_loc (input_location, MINUS_EXPR,
1697 gfc_array_index_type,
1698 offset, tmp);
1700 if (need_len_assign)
1702 if (e->symtree
1703 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1704 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1705 /* Use the original class descriptor stored in the saved
1706 descriptor to get the target_expr. */
1707 target_expr =
1708 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1709 else
1710 /* Strip the _data component from the target_expr. */
1711 target_expr = TREE_OPERAND (target_expr, 0);
1712 /* Add a reference to the _len comp to the target expr. */
1713 tmp = gfc_class_len_get (target_expr);
1714 /* Get the component-ref for the temp structure's _len comp. */
1715 charlen = gfc_class_len_get (se.expr);
1716 /* Add the assign to the beginning of the block... */
1717 gfc_add_modify (&se.pre, charlen,
1718 fold_convert (TREE_TYPE (charlen), tmp));
1719 /* and the oposite way at the end of the block, to hand changes
1720 on the string length back. */
1721 gfc_add_modify (&se.post, tmp,
1722 fold_convert (TREE_TYPE (tmp), charlen));
1723 /* Length assignment done, prevent adding it again below. */
1724 need_len_assign = false;
1726 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1728 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1729 && CLASS_DATA (e)->attr.dimension)
1731 /* This is bound to be a class array element. */
1732 gfc_conv_expr_reference (&se, e);
1733 /* Get the _vptr component of the class object. */
1734 tmp = gfc_get_vptr_from_expr (se.expr);
1735 /* Obtain a temporary class container for the result. */
1736 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1737 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1739 else
1741 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1742 which has the string length included. For CHARACTERS it is still
1743 needed and will be done at the end of this routine. */
1744 gfc_conv_expr (&se, e);
1745 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1748 tmp = TREE_TYPE (sym->backend_decl);
1749 tmp = gfc_build_addr_expr (tmp, se.expr);
1750 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1752 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1753 gfc_finish_block (&se.post));
1756 /* Do a simple assignment. This is for scalar expressions, where we
1757 can simply use expression assignment. */
1758 else
1760 gfc_expr *lhs;
1762 lhs = gfc_lval_expr_from_sym (sym);
1763 tmp = gfc_trans_assignment (lhs, e, false, true);
1764 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1767 /* Set the stringlength, when needed. */
1768 if (need_len_assign)
1770 gfc_se se;
1771 gfc_init_se (&se, NULL);
1772 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1774 /* What about deferred strings? */
1775 gcc_assert (!e->symtree->n.sym->ts.deferred);
1776 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1778 else
1779 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1780 gfc_get_symbol_decl (sym);
1781 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1782 : gfc_class_len_get (sym->backend_decl);
1783 /* Prevent adding a noop len= len. */
1784 if (tmp != charlen)
1786 gfc_add_modify (&se.pre, charlen,
1787 fold_convert (TREE_TYPE (charlen), tmp));
1788 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1789 gfc_finish_block (&se.post));
1795 /* Translate a BLOCK construct. This is basically what we would do for a
1796 procedure body. */
1798 tree
1799 gfc_trans_block_construct (gfc_code* code)
1801 gfc_namespace* ns;
1802 gfc_symbol* sym;
1803 gfc_wrapped_block block;
1804 tree exit_label;
1805 stmtblock_t body;
1806 gfc_association_list *ass;
1808 ns = code->ext.block.ns;
1809 gcc_assert (ns);
1810 sym = ns->proc_name;
1811 gcc_assert (sym);
1813 /* Process local variables. */
1814 gcc_assert (!sym->tlink);
1815 sym->tlink = sym;
1816 gfc_process_block_locals (ns);
1818 /* Generate code including exit-label. */
1819 gfc_init_block (&body);
1820 exit_label = gfc_build_label_decl (NULL_TREE);
1821 code->exit_label = exit_label;
1823 finish_oacc_declare (ns, sym, true);
1825 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1826 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1828 /* Finish everything. */
1829 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1830 gfc_trans_deferred_vars (sym, &block);
1831 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1832 trans_associate_var (ass->st->n.sym, &block);
1834 return gfc_finish_wrapped_block (&block);
1837 /* Translate the simple DO construct in a C-style manner.
1838 This is where the loop variable has integer type and step +-1.
1839 Following code will generate infinite loop in case where TO is INT_MAX
1840 (for +1 step) or INT_MIN (for -1 step)
1842 We translate a do loop from:
1844 DO dovar = from, to, step
1845 body
1846 END DO
1850 [Evaluate loop bounds and step]
1851 dovar = from;
1852 for (;;)
1854 if (dovar > to)
1855 goto end_label;
1856 body;
1857 cycle_label:
1858 dovar += step;
1860 end_label:
1862 This helps the optimizers by avoiding the extra pre-header condition and
1863 we save a register as we just compare the updated IV (not a value in
1864 previous step). */
1866 static tree
1867 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1868 tree from, tree to, tree step, tree exit_cond)
1870 stmtblock_t body;
1871 tree type;
1872 tree cond;
1873 tree tmp;
1874 tree saved_dovar = NULL;
1875 tree cycle_label;
1876 tree exit_label;
1877 location_t loc;
1878 type = TREE_TYPE (dovar);
1879 bool is_step_positive = tree_int_cst_sgn (step) > 0;
1881 loc = code->ext.iterator->start->where.lb->location;
1883 /* Initialize the DO variable: dovar = from. */
1884 gfc_add_modify_loc (loc, pblock, dovar,
1885 fold_convert (TREE_TYPE (dovar), from));
1887 /* Save value for do-tinkering checking. */
1888 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1890 saved_dovar = gfc_create_var (type, ".saved_dovar");
1891 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1894 /* Cycle and exit statements are implemented with gotos. */
1895 cycle_label = gfc_build_label_decl (NULL_TREE);
1896 exit_label = gfc_build_label_decl (NULL_TREE);
1898 /* Put the labels where they can be found later. See gfc_trans_do(). */
1899 code->cycle_label = cycle_label;
1900 code->exit_label = exit_label;
1902 /* Loop body. */
1903 gfc_start_block (&body);
1905 /* Exit the loop if there is an I/O result condition or error. */
1906 if (exit_cond)
1908 tmp = build1_v (GOTO_EXPR, exit_label);
1909 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1910 exit_cond, tmp,
1911 build_empty_stmt (loc));
1912 gfc_add_expr_to_block (&body, tmp);
1915 /* Evaluate the loop condition. */
1916 if (is_step_positive)
1917 cond = fold_build2_loc (loc, GT_EXPR, boolean_type_node, dovar,
1918 fold_convert (type, to));
1919 else
1920 cond = fold_build2_loc (loc, LT_EXPR, boolean_type_node, dovar,
1921 fold_convert (type, to));
1923 cond = gfc_evaluate_now_loc (loc, cond, &body);
1925 /* The loop exit. */
1926 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1927 TREE_USED (exit_label) = 1;
1928 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1929 cond, tmp, build_empty_stmt (loc));
1930 gfc_add_expr_to_block (&body, tmp);
1932 /* Check whether the induction variable is equal to INT_MAX
1933 (respectively to INT_MIN). */
1934 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1936 tree boundary = is_step_positive ? TYPE_MAX_VALUE (type)
1937 : TYPE_MIN_VALUE (type);
1939 tmp = fold_build2_loc (loc, EQ_EXPR, boolean_type_node,
1940 dovar, boundary);
1941 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1942 "Loop iterates infinitely");
1945 /* Main loop body. */
1946 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1947 gfc_add_expr_to_block (&body, tmp);
1949 /* Label for cycle statements (if needed). */
1950 if (TREE_USED (cycle_label))
1952 tmp = build1_v (LABEL_EXPR, cycle_label);
1953 gfc_add_expr_to_block (&body, tmp);
1956 /* Check whether someone has modified the loop variable. */
1957 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1959 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1960 dovar, saved_dovar);
1961 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1962 "Loop variable has been modified");
1965 /* Increment the loop variable. */
1966 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1967 gfc_add_modify_loc (loc, &body, dovar, tmp);
1969 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1970 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1972 /* Finish the loop body. */
1973 tmp = gfc_finish_block (&body);
1974 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1976 gfc_add_expr_to_block (pblock, tmp);
1978 /* Add the exit label. */
1979 tmp = build1_v (LABEL_EXPR, exit_label);
1980 gfc_add_expr_to_block (pblock, tmp);
1982 return gfc_finish_block (pblock);
1985 /* Translate the DO construct. This obviously is one of the most
1986 important ones to get right with any compiler, but especially
1987 so for Fortran.
1989 We special case some loop forms as described in gfc_trans_simple_do.
1990 For other cases we implement them with a separate loop count,
1991 as described in the standard.
1993 We translate a do loop from:
1995 DO dovar = from, to, step
1996 body
1997 END DO
2001 [evaluate loop bounds and step]
2002 empty = (step > 0 ? to < from : to > from);
2003 countm1 = (to - from) / step;
2004 dovar = from;
2005 if (empty) goto exit_label;
2006 for (;;)
2008 body;
2009 cycle_label:
2010 dovar += step
2011 countm1t = countm1;
2012 countm1--;
2013 if (countm1t == 0) goto exit_label;
2015 exit_label:
2017 countm1 is an unsigned integer. It is equal to the loop count minus one,
2018 because the loop count itself can overflow. */
2020 tree
2021 gfc_trans_do (gfc_code * code, tree exit_cond)
2023 gfc_se se;
2024 tree dovar;
2025 tree saved_dovar = NULL;
2026 tree from;
2027 tree to;
2028 tree step;
2029 tree countm1;
2030 tree type;
2031 tree utype;
2032 tree cond;
2033 tree cycle_label;
2034 tree exit_label;
2035 tree tmp;
2036 stmtblock_t block;
2037 stmtblock_t body;
2038 location_t loc;
2040 gfc_start_block (&block);
2042 loc = code->ext.iterator->start->where.lb->location;
2044 /* Evaluate all the expressions in the iterator. */
2045 gfc_init_se (&se, NULL);
2046 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
2047 gfc_add_block_to_block (&block, &se.pre);
2048 dovar = se.expr;
2049 type = TREE_TYPE (dovar);
2051 gfc_init_se (&se, NULL);
2052 gfc_conv_expr_val (&se, code->ext.iterator->start);
2053 gfc_add_block_to_block (&block, &se.pre);
2054 from = gfc_evaluate_now (se.expr, &block);
2056 gfc_init_se (&se, NULL);
2057 gfc_conv_expr_val (&se, code->ext.iterator->end);
2058 gfc_add_block_to_block (&block, &se.pre);
2059 to = gfc_evaluate_now (se.expr, &block);
2061 gfc_init_se (&se, NULL);
2062 gfc_conv_expr_val (&se, code->ext.iterator->step);
2063 gfc_add_block_to_block (&block, &se.pre);
2064 step = gfc_evaluate_now (se.expr, &block);
2066 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2068 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
2069 build_zero_cst (type));
2070 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
2071 "DO step value is zero");
2074 /* Special case simple loops. */
2075 if (TREE_CODE (type) == INTEGER_TYPE
2076 && (integer_onep (step)
2077 || tree_int_cst_equal (step, integer_minus_one_node)))
2078 return gfc_trans_simple_do (code, &block, dovar, from, to, step,
2079 exit_cond);
2081 if (TREE_CODE (type) == INTEGER_TYPE)
2082 utype = unsigned_type_for (type);
2083 else
2084 utype = unsigned_type_for (gfc_array_index_type);
2085 countm1 = gfc_create_var (utype, "countm1");
2087 /* Cycle and exit statements are implemented with gotos. */
2088 cycle_label = gfc_build_label_decl (NULL_TREE);
2089 exit_label = gfc_build_label_decl (NULL_TREE);
2090 TREE_USED (exit_label) = 1;
2092 /* Put these labels where they can be found later. */
2093 code->cycle_label = cycle_label;
2094 code->exit_label = exit_label;
2096 /* Initialize the DO variable: dovar = from. */
2097 gfc_add_modify (&block, dovar, from);
2099 /* Save value for do-tinkering checking. */
2100 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2102 saved_dovar = gfc_create_var (type, ".saved_dovar");
2103 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
2106 /* Initialize loop count and jump to exit label if the loop is empty.
2107 This code is executed before we enter the loop body. We generate:
2108 if (step > 0)
2110 countm1 = (to - from) / step;
2111 if (to < from)
2112 goto exit_label;
2114 else
2116 countm1 = (from - to) / -step;
2117 if (to > from)
2118 goto exit_label;
2122 if (TREE_CODE (type) == INTEGER_TYPE)
2124 tree pos, neg, tou, fromu, stepu, tmp2;
2126 /* The distance from FROM to TO cannot always be represented in a signed
2127 type, thus use unsigned arithmetic, also to avoid any undefined
2128 overflow issues. */
2129 tou = fold_convert (utype, to);
2130 fromu = fold_convert (utype, from);
2131 stepu = fold_convert (utype, step);
2133 /* For a positive step, when to < from, exit, otherwise compute
2134 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
2135 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
2136 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2137 fold_build2_loc (loc, MINUS_EXPR, utype,
2138 tou, fromu),
2139 stepu);
2140 pos = build2 (COMPOUND_EXPR, void_type_node,
2141 fold_build2 (MODIFY_EXPR, void_type_node,
2142 countm1, tmp2),
2143 build3_loc (loc, COND_EXPR, void_type_node,
2144 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2145 build1_loc (loc, GOTO_EXPR, void_type_node,
2146 exit_label), NULL_TREE));
2148 /* For a negative step, when to > from, exit, otherwise compute
2149 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
2150 tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, to, from);
2151 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
2152 fold_build2_loc (loc, MINUS_EXPR, utype,
2153 fromu, tou),
2154 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
2155 neg = build2 (COMPOUND_EXPR, void_type_node,
2156 fold_build2 (MODIFY_EXPR, void_type_node,
2157 countm1, tmp2),
2158 build3_loc (loc, COND_EXPR, void_type_node,
2159 gfc_unlikely (tmp, PRED_FORTRAN_LOOP_PREHEADER),
2160 build1_loc (loc, GOTO_EXPR, void_type_node,
2161 exit_label), NULL_TREE));
2163 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
2164 build_int_cst (TREE_TYPE (step), 0));
2165 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
2167 gfc_add_expr_to_block (&block, tmp);
2169 else
2171 tree pos_step;
2173 /* TODO: We could use the same width as the real type.
2174 This would probably cause more problems that it solves
2175 when we implement "long double" types. */
2177 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
2178 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
2179 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
2180 gfc_add_modify (&block, countm1, tmp);
2182 /* We need a special check for empty loops:
2183 empty = (step > 0 ? to < from : to > from); */
2184 pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
2185 build_zero_cst (type));
2186 tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
2187 fold_build2_loc (loc, LT_EXPR,
2188 boolean_type_node, to, from),
2189 fold_build2_loc (loc, GT_EXPR,
2190 boolean_type_node, to, from));
2191 /* If the loop is empty, go directly to the exit label. */
2192 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
2193 build1_v (GOTO_EXPR, exit_label),
2194 build_empty_stmt (input_location));
2195 gfc_add_expr_to_block (&block, tmp);
2198 /* Loop body. */
2199 gfc_start_block (&body);
2201 /* Main loop body. */
2202 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
2203 gfc_add_expr_to_block (&body, tmp);
2205 /* Label for cycle statements (if needed). */
2206 if (TREE_USED (cycle_label))
2208 tmp = build1_v (LABEL_EXPR, cycle_label);
2209 gfc_add_expr_to_block (&body, tmp);
2212 /* Check whether someone has modified the loop variable. */
2213 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2215 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
2216 saved_dovar);
2217 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
2218 "Loop variable has been modified");
2221 /* Exit the loop if there is an I/O result condition or error. */
2222 if (exit_cond)
2224 tmp = build1_v (GOTO_EXPR, exit_label);
2225 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2226 exit_cond, tmp,
2227 build_empty_stmt (input_location));
2228 gfc_add_expr_to_block (&body, tmp);
2231 /* Increment the loop variable. */
2232 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
2233 gfc_add_modify_loc (loc, &body, dovar, tmp);
2235 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
2236 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2238 /* Initialize countm1t. */
2239 tree countm1t = gfc_create_var (utype, "countm1t");
2240 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2242 /* Decrement the loop count. */
2243 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2244 build_int_cst (utype, 1));
2245 gfc_add_modify_loc (loc, &body, countm1, tmp);
2247 /* End with the loop condition. Loop until countm1t == 0. */
2248 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, countm1t,
2249 build_int_cst (utype, 0));
2250 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2251 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2252 cond, tmp, build_empty_stmt (loc));
2253 gfc_add_expr_to_block (&body, tmp);
2255 /* End of loop body. */
2256 tmp = gfc_finish_block (&body);
2258 /* The for loop itself. */
2259 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2260 gfc_add_expr_to_block (&block, tmp);
2262 /* Add the exit label. */
2263 tmp = build1_v (LABEL_EXPR, exit_label);
2264 gfc_add_expr_to_block (&block, tmp);
2266 return gfc_finish_block (&block);
2270 /* Translate the DO WHILE construct.
2272 We translate
2274 DO WHILE (cond)
2275 body
2276 END DO
2280 for ( ; ; )
2282 pre_cond;
2283 if (! cond) goto exit_label;
2284 body;
2285 cycle_label:
2287 exit_label:
2289 Because the evaluation of the exit condition `cond' may have side
2290 effects, we can't do much for empty loop bodies. The backend optimizers
2291 should be smart enough to eliminate any dead loops. */
2293 tree
2294 gfc_trans_do_while (gfc_code * code)
2296 gfc_se cond;
2297 tree tmp;
2298 tree cycle_label;
2299 tree exit_label;
2300 stmtblock_t block;
2302 /* Everything we build here is part of the loop body. */
2303 gfc_start_block (&block);
2305 /* Cycle and exit statements are implemented with gotos. */
2306 cycle_label = gfc_build_label_decl (NULL_TREE);
2307 exit_label = gfc_build_label_decl (NULL_TREE);
2309 /* Put the labels where they can be found later. See gfc_trans_do(). */
2310 code->cycle_label = cycle_label;
2311 code->exit_label = exit_label;
2313 /* Create a GIMPLE version of the exit condition. */
2314 gfc_init_se (&cond, NULL);
2315 gfc_conv_expr_val (&cond, code->expr1);
2316 gfc_add_block_to_block (&block, &cond.pre);
2317 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2318 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2320 /* Build "IF (! cond) GOTO exit_label". */
2321 tmp = build1_v (GOTO_EXPR, exit_label);
2322 TREE_USED (exit_label) = 1;
2323 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2324 void_type_node, cond.expr, tmp,
2325 build_empty_stmt (code->expr1->where.lb->location));
2326 gfc_add_expr_to_block (&block, tmp);
2328 /* The main body of the loop. */
2329 tmp = gfc_trans_code (code->block->next);
2330 gfc_add_expr_to_block (&block, tmp);
2332 /* Label for cycle statements (if needed). */
2333 if (TREE_USED (cycle_label))
2335 tmp = build1_v (LABEL_EXPR, cycle_label);
2336 gfc_add_expr_to_block (&block, tmp);
2339 /* End of loop body. */
2340 tmp = gfc_finish_block (&block);
2342 gfc_init_block (&block);
2343 /* Build the loop. */
2344 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2345 void_type_node, tmp);
2346 gfc_add_expr_to_block (&block, tmp);
2348 /* Add the exit label. */
2349 tmp = build1_v (LABEL_EXPR, exit_label);
2350 gfc_add_expr_to_block (&block, tmp);
2352 return gfc_finish_block (&block);
2356 /* Deal with the particular case of SELECT_TYPE, where the vtable
2357 addresses are used for the selection. Since these are not sorted,
2358 the selection has to be made by a series of if statements. */
2360 static tree
2361 gfc_trans_select_type_cases (gfc_code * code)
2363 gfc_code *c;
2364 gfc_case *cp;
2365 tree tmp;
2366 tree cond;
2367 tree low;
2368 tree high;
2369 gfc_se se;
2370 gfc_se cse;
2371 stmtblock_t block;
2372 stmtblock_t body;
2373 bool def = false;
2374 gfc_expr *e;
2375 gfc_start_block (&block);
2377 /* Calculate the switch expression. */
2378 gfc_init_se (&se, NULL);
2379 gfc_conv_expr_val (&se, code->expr1);
2380 gfc_add_block_to_block (&block, &se.pre);
2382 /* Generate an expression for the selector hash value, for
2383 use to resolve character cases. */
2384 e = gfc_copy_expr (code->expr1->value.function.actual->expr);
2385 gfc_add_hash_component (e);
2387 TREE_USED (code->exit_label) = 0;
2389 repeat:
2390 for (c = code->block; c; c = c->block)
2392 cp = c->ext.block.case_list;
2394 /* Assume it's the default case. */
2395 low = NULL_TREE;
2396 high = NULL_TREE;
2397 tmp = NULL_TREE;
2399 /* Put the default case at the end. */
2400 if ((!def && !cp->low) || (def && cp->low))
2401 continue;
2403 if (cp->low && (cp->ts.type == BT_CLASS
2404 || cp->ts.type == BT_DERIVED))
2406 gfc_init_se (&cse, NULL);
2407 gfc_conv_expr_val (&cse, cp->low);
2408 gfc_add_block_to_block (&block, &cse.pre);
2409 low = cse.expr;
2411 else if (cp->ts.type != BT_UNKNOWN)
2413 gcc_assert (cp->high);
2414 gfc_init_se (&cse, NULL);
2415 gfc_conv_expr_val (&cse, cp->high);
2416 gfc_add_block_to_block (&block, &cse.pre);
2417 high = cse.expr;
2420 gfc_init_block (&body);
2422 /* Add the statements for this case. */
2423 tmp = gfc_trans_code (c->next);
2424 gfc_add_expr_to_block (&body, tmp);
2426 /* Break to the end of the SELECT TYPE construct. The default
2427 case just falls through. */
2428 if (!def)
2430 TREE_USED (code->exit_label) = 1;
2431 tmp = build1_v (GOTO_EXPR, code->exit_label);
2432 gfc_add_expr_to_block (&body, tmp);
2435 tmp = gfc_finish_block (&body);
2437 if (low != NULL_TREE)
2439 /* Compare vtable pointers. */
2440 cond = fold_build2_loc (input_location, EQ_EXPR,
2441 TREE_TYPE (se.expr), se.expr, low);
2442 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2443 cond, tmp,
2444 build_empty_stmt (input_location));
2446 else if (high != NULL_TREE)
2448 /* Compare hash values for character cases. */
2449 gfc_init_se (&cse, NULL);
2450 gfc_conv_expr_val (&cse, e);
2451 gfc_add_block_to_block (&block, &cse.pre);
2453 cond = fold_build2_loc (input_location, EQ_EXPR,
2454 TREE_TYPE (se.expr), high, cse.expr);
2455 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2456 cond, tmp,
2457 build_empty_stmt (input_location));
2460 gfc_add_expr_to_block (&block, tmp);
2463 if (!def)
2465 def = true;
2466 goto repeat;
2469 gfc_free_expr (e);
2471 return gfc_finish_block (&block);
2475 /* Translate the SELECT CASE construct for INTEGER case expressions,
2476 without killing all potential optimizations. The problem is that
2477 Fortran allows unbounded cases, but the back-end does not, so we
2478 need to intercept those before we enter the equivalent SWITCH_EXPR
2479 we can build.
2481 For example, we translate this,
2483 SELECT CASE (expr)
2484 CASE (:100,101,105:115)
2485 block_1
2486 CASE (190:199,200:)
2487 block_2
2488 CASE (300)
2489 block_3
2490 CASE DEFAULT
2491 block_4
2492 END SELECT
2494 to the GENERIC equivalent,
2496 switch (expr)
2498 case (minimum value for typeof(expr) ... 100:
2499 case 101:
2500 case 105 ... 114:
2501 block1:
2502 goto end_label;
2504 case 200 ... (maximum value for typeof(expr):
2505 case 190 ... 199:
2506 block2;
2507 goto end_label;
2509 case 300:
2510 block_3;
2511 goto end_label;
2513 default:
2514 block_4;
2515 goto end_label;
2518 end_label: */
2520 static tree
2521 gfc_trans_integer_select (gfc_code * code)
2523 gfc_code *c;
2524 gfc_case *cp;
2525 tree end_label;
2526 tree tmp;
2527 gfc_se se;
2528 stmtblock_t block;
2529 stmtblock_t body;
2531 gfc_start_block (&block);
2533 /* Calculate the switch expression. */
2534 gfc_init_se (&se, NULL);
2535 gfc_conv_expr_val (&se, code->expr1);
2536 gfc_add_block_to_block (&block, &se.pre);
2538 end_label = gfc_build_label_decl (NULL_TREE);
2540 gfc_init_block (&body);
2542 for (c = code->block; c; c = c->block)
2544 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2546 tree low, high;
2547 tree label;
2549 /* Assume it's the default case. */
2550 low = high = NULL_TREE;
2552 if (cp->low)
2554 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2555 cp->low->ts.kind);
2557 /* If there's only a lower bound, set the high bound to the
2558 maximum value of the case expression. */
2559 if (!cp->high)
2560 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2563 if (cp->high)
2565 /* Three cases are possible here:
2567 1) There is no lower bound, e.g. CASE (:N).
2568 2) There is a lower bound .NE. high bound, that is
2569 a case range, e.g. CASE (N:M) where M>N (we make
2570 sure that M>N during type resolution).
2571 3) There is a lower bound, and it has the same value
2572 as the high bound, e.g. CASE (N:N). This is our
2573 internal representation of CASE(N).
2575 In the first and second case, we need to set a value for
2576 high. In the third case, we don't because the GCC middle
2577 end represents a single case value by just letting high be
2578 a NULL_TREE. We can't do that because we need to be able
2579 to represent unbounded cases. */
2581 if (!cp->low
2582 || (mpz_cmp (cp->low->value.integer,
2583 cp->high->value.integer) != 0))
2584 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2585 cp->high->ts.kind);
2587 /* Unbounded case. */
2588 if (!cp->low)
2589 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2592 /* Build a label. */
2593 label = gfc_build_label_decl (NULL_TREE);
2595 /* Add this case label.
2596 Add parameter 'label', make it match GCC backend. */
2597 tmp = build_case_label (low, high, label);
2598 gfc_add_expr_to_block (&body, tmp);
2601 /* Add the statements for this case. */
2602 tmp = gfc_trans_code (c->next);
2603 gfc_add_expr_to_block (&body, tmp);
2605 /* Break to the end of the construct. */
2606 tmp = build1_v (GOTO_EXPR, end_label);
2607 gfc_add_expr_to_block (&body, tmp);
2610 tmp = gfc_finish_block (&body);
2611 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2612 se.expr, tmp, NULL_TREE);
2613 gfc_add_expr_to_block (&block, tmp);
2615 tmp = build1_v (LABEL_EXPR, end_label);
2616 gfc_add_expr_to_block (&block, tmp);
2618 return gfc_finish_block (&block);
2622 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2624 There are only two cases possible here, even though the standard
2625 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2626 .FALSE., and DEFAULT.
2628 We never generate more than two blocks here. Instead, we always
2629 try to eliminate the DEFAULT case. This way, we can translate this
2630 kind of SELECT construct to a simple
2632 if {} else {};
2634 expression in GENERIC. */
2636 static tree
2637 gfc_trans_logical_select (gfc_code * code)
2639 gfc_code *c;
2640 gfc_code *t, *f, *d;
2641 gfc_case *cp;
2642 gfc_se se;
2643 stmtblock_t block;
2645 /* Assume we don't have any cases at all. */
2646 t = f = d = NULL;
2648 /* Now see which ones we actually do have. We can have at most two
2649 cases in a single case list: one for .TRUE. and one for .FALSE.
2650 The default case is always separate. If the cases for .TRUE. and
2651 .FALSE. are in the same case list, the block for that case list
2652 always executed, and we don't generate code a COND_EXPR. */
2653 for (c = code->block; c; c = c->block)
2655 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2657 if (cp->low)
2659 if (cp->low->value.logical == 0) /* .FALSE. */
2660 f = c;
2661 else /* if (cp->value.logical != 0), thus .TRUE. */
2662 t = c;
2664 else
2665 d = c;
2669 /* Start a new block. */
2670 gfc_start_block (&block);
2672 /* Calculate the switch expression. We always need to do this
2673 because it may have side effects. */
2674 gfc_init_se (&se, NULL);
2675 gfc_conv_expr_val (&se, code->expr1);
2676 gfc_add_block_to_block (&block, &se.pre);
2678 if (t == f && t != NULL)
2680 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2681 translate the code for these cases, append it to the current
2682 block. */
2683 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2685 else
2687 tree true_tree, false_tree, stmt;
2689 true_tree = build_empty_stmt (input_location);
2690 false_tree = build_empty_stmt (input_location);
2692 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2693 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2694 make the missing case the default case. */
2695 if (t != NULL && f != NULL)
2696 d = NULL;
2697 else if (d != NULL)
2699 if (t == NULL)
2700 t = d;
2701 else
2702 f = d;
2705 /* Translate the code for each of these blocks, and append it to
2706 the current block. */
2707 if (t != NULL)
2708 true_tree = gfc_trans_code (t->next);
2710 if (f != NULL)
2711 false_tree = gfc_trans_code (f->next);
2713 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2714 se.expr, true_tree, false_tree);
2715 gfc_add_expr_to_block (&block, stmt);
2718 return gfc_finish_block (&block);
2722 /* The jump table types are stored in static variables to avoid
2723 constructing them from scratch every single time. */
2724 static GTY(()) tree select_struct[2];
2726 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2727 Instead of generating compares and jumps, it is far simpler to
2728 generate a data structure describing the cases in order and call a
2729 library subroutine that locates the right case.
2730 This is particularly true because this is the only case where we
2731 might have to dispose of a temporary.
2732 The library subroutine returns a pointer to jump to or NULL if no
2733 branches are to be taken. */
2735 static tree
2736 gfc_trans_character_select (gfc_code *code)
2738 tree init, end_label, tmp, type, case_num, label, fndecl;
2739 stmtblock_t block, body;
2740 gfc_case *cp, *d;
2741 gfc_code *c;
2742 gfc_se se, expr1se;
2743 int n, k;
2744 vec<constructor_elt, va_gc> *inits = NULL;
2746 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2748 /* The jump table types are stored in static variables to avoid
2749 constructing them from scratch every single time. */
2750 static tree ss_string1[2], ss_string1_len[2];
2751 static tree ss_string2[2], ss_string2_len[2];
2752 static tree ss_target[2];
2754 cp = code->block->ext.block.case_list;
2755 while (cp->left != NULL)
2756 cp = cp->left;
2758 /* Generate the body */
2759 gfc_start_block (&block);
2760 gfc_init_se (&expr1se, NULL);
2761 gfc_conv_expr_reference (&expr1se, code->expr1);
2763 gfc_add_block_to_block (&block, &expr1se.pre);
2765 end_label = gfc_build_label_decl (NULL_TREE);
2767 gfc_init_block (&body);
2769 /* Attempt to optimize length 1 selects. */
2770 if (integer_onep (expr1se.string_length))
2772 for (d = cp; d; d = d->right)
2774 int i;
2775 if (d->low)
2777 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2778 && d->low->ts.type == BT_CHARACTER);
2779 if (d->low->value.character.length > 1)
2781 for (i = 1; i < d->low->value.character.length; i++)
2782 if (d->low->value.character.string[i] != ' ')
2783 break;
2784 if (i != d->low->value.character.length)
2786 if (optimize && d->high && i == 1)
2788 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2789 && d->high->ts.type == BT_CHARACTER);
2790 if (d->high->value.character.length > 1
2791 && (d->low->value.character.string[0]
2792 == d->high->value.character.string[0])
2793 && d->high->value.character.string[1] != ' '
2794 && ((d->low->value.character.string[1] < ' ')
2795 == (d->high->value.character.string[1]
2796 < ' ')))
2797 continue;
2799 break;
2803 if (d->high)
2805 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2806 && d->high->ts.type == BT_CHARACTER);
2807 if (d->high->value.character.length > 1)
2809 for (i = 1; i < d->high->value.character.length; i++)
2810 if (d->high->value.character.string[i] != ' ')
2811 break;
2812 if (i != d->high->value.character.length)
2813 break;
2817 if (d == NULL)
2819 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2821 for (c = code->block; c; c = c->block)
2823 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2825 tree low, high;
2826 tree label;
2827 gfc_char_t r;
2829 /* Assume it's the default case. */
2830 low = high = NULL_TREE;
2832 if (cp->low)
2834 /* CASE ('ab') or CASE ('ab':'az') will never match
2835 any length 1 character. */
2836 if (cp->low->value.character.length > 1
2837 && cp->low->value.character.string[1] != ' ')
2838 continue;
2840 if (cp->low->value.character.length > 0)
2841 r = cp->low->value.character.string[0];
2842 else
2843 r = ' ';
2844 low = build_int_cst (ctype, r);
2846 /* If there's only a lower bound, set the high bound
2847 to the maximum value of the case expression. */
2848 if (!cp->high)
2849 high = TYPE_MAX_VALUE (ctype);
2852 if (cp->high)
2854 if (!cp->low
2855 || (cp->low->value.character.string[0]
2856 != cp->high->value.character.string[0]))
2858 if (cp->high->value.character.length > 0)
2859 r = cp->high->value.character.string[0];
2860 else
2861 r = ' ';
2862 high = build_int_cst (ctype, r);
2865 /* Unbounded case. */
2866 if (!cp->low)
2867 low = TYPE_MIN_VALUE (ctype);
2870 /* Build a label. */
2871 label = gfc_build_label_decl (NULL_TREE);
2873 /* Add this case label.
2874 Add parameter 'label', make it match GCC backend. */
2875 tmp = build_case_label (low, high, label);
2876 gfc_add_expr_to_block (&body, tmp);
2879 /* Add the statements for this case. */
2880 tmp = gfc_trans_code (c->next);
2881 gfc_add_expr_to_block (&body, tmp);
2883 /* Break to the end of the construct. */
2884 tmp = build1_v (GOTO_EXPR, end_label);
2885 gfc_add_expr_to_block (&body, tmp);
2888 tmp = gfc_string_to_single_character (expr1se.string_length,
2889 expr1se.expr,
2890 code->expr1->ts.kind);
2891 case_num = gfc_create_var (ctype, "case_num");
2892 gfc_add_modify (&block, case_num, tmp);
2894 gfc_add_block_to_block (&block, &expr1se.post);
2896 tmp = gfc_finish_block (&body);
2897 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2898 case_num, tmp, NULL_TREE);
2899 gfc_add_expr_to_block (&block, tmp);
2901 tmp = build1_v (LABEL_EXPR, end_label);
2902 gfc_add_expr_to_block (&block, tmp);
2904 return gfc_finish_block (&block);
2908 if (code->expr1->ts.kind == 1)
2909 k = 0;
2910 else if (code->expr1->ts.kind == 4)
2911 k = 1;
2912 else
2913 gcc_unreachable ();
2915 if (select_struct[k] == NULL)
2917 tree *chain = NULL;
2918 select_struct[k] = make_node (RECORD_TYPE);
2920 if (code->expr1->ts.kind == 1)
2921 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2922 else if (code->expr1->ts.kind == 4)
2923 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2924 else
2925 gcc_unreachable ();
2927 #undef ADD_FIELD
2928 #define ADD_FIELD(NAME, TYPE) \
2929 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2930 get_identifier (stringize(NAME)), \
2931 TYPE, \
2932 &chain)
2934 ADD_FIELD (string1, pchartype);
2935 ADD_FIELD (string1_len, gfc_charlen_type_node);
2937 ADD_FIELD (string2, pchartype);
2938 ADD_FIELD (string2_len, gfc_charlen_type_node);
2940 ADD_FIELD (target, integer_type_node);
2941 #undef ADD_FIELD
2943 gfc_finish_type (select_struct[k]);
2946 n = 0;
2947 for (d = cp; d; d = d->right)
2948 d->n = n++;
2950 for (c = code->block; c; c = c->block)
2952 for (d = c->ext.block.case_list; d; d = d->next)
2954 label = gfc_build_label_decl (NULL_TREE);
2955 tmp = build_case_label ((d->low == NULL && d->high == NULL)
2956 ? NULL
2957 : build_int_cst (integer_type_node, d->n),
2958 NULL, label);
2959 gfc_add_expr_to_block (&body, tmp);
2962 tmp = gfc_trans_code (c->next);
2963 gfc_add_expr_to_block (&body, tmp);
2965 tmp = build1_v (GOTO_EXPR, end_label);
2966 gfc_add_expr_to_block (&body, tmp);
2969 /* Generate the structure describing the branches */
2970 for (d = cp; d; d = d->right)
2972 vec<constructor_elt, va_gc> *node = NULL;
2974 gfc_init_se (&se, NULL);
2976 if (d->low == NULL)
2978 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2979 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2981 else
2983 gfc_conv_expr_reference (&se, d->low);
2985 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2986 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2989 if (d->high == NULL)
2991 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2992 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2994 else
2996 gfc_init_se (&se, NULL);
2997 gfc_conv_expr_reference (&se, d->high);
2999 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
3000 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
3003 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
3004 build_int_cst (integer_type_node, d->n));
3006 tmp = build_constructor (select_struct[k], node);
3007 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
3010 type = build_array_type (select_struct[k],
3011 build_index_type (size_int (n-1)));
3013 init = build_constructor (type, inits);
3014 TREE_CONSTANT (init) = 1;
3015 TREE_STATIC (init) = 1;
3016 /* Create a static variable to hold the jump table. */
3017 tmp = gfc_create_var (type, "jumptable");
3018 TREE_CONSTANT (tmp) = 1;
3019 TREE_STATIC (tmp) = 1;
3020 TREE_READONLY (tmp) = 1;
3021 DECL_INITIAL (tmp) = init;
3022 init = tmp;
3024 /* Build the library call */
3025 init = gfc_build_addr_expr (pvoid_type_node, init);
3027 if (code->expr1->ts.kind == 1)
3028 fndecl = gfor_fndecl_select_string;
3029 else if (code->expr1->ts.kind == 4)
3030 fndecl = gfor_fndecl_select_string_char4;
3031 else
3032 gcc_unreachable ();
3034 tmp = build_call_expr_loc (input_location,
3035 fndecl, 4, init,
3036 build_int_cst (gfc_charlen_type_node, n),
3037 expr1se.expr, expr1se.string_length);
3038 case_num = gfc_create_var (integer_type_node, "case_num");
3039 gfc_add_modify (&block, case_num, tmp);
3041 gfc_add_block_to_block (&block, &expr1se.post);
3043 tmp = gfc_finish_block (&body);
3044 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
3045 case_num, tmp, NULL_TREE);
3046 gfc_add_expr_to_block (&block, tmp);
3048 tmp = build1_v (LABEL_EXPR, end_label);
3049 gfc_add_expr_to_block (&block, tmp);
3051 return gfc_finish_block (&block);
3055 /* Translate the three variants of the SELECT CASE construct.
3057 SELECT CASEs with INTEGER case expressions can be translated to an
3058 equivalent GENERIC switch statement, and for LOGICAL case
3059 expressions we build one or two if-else compares.
3061 SELECT CASEs with CHARACTER case expressions are a whole different
3062 story, because they don't exist in GENERIC. So we sort them and
3063 do a binary search at runtime.
3065 Fortran has no BREAK statement, and it does not allow jumps from
3066 one case block to another. That makes things a lot easier for
3067 the optimizers. */
3069 tree
3070 gfc_trans_select (gfc_code * code)
3072 stmtblock_t block;
3073 tree body;
3074 tree exit_label;
3076 gcc_assert (code && code->expr1);
3077 gfc_init_block (&block);
3079 /* Build the exit label and hang it in. */
3080 exit_label = gfc_build_label_decl (NULL_TREE);
3081 code->exit_label = exit_label;
3083 /* Empty SELECT constructs are legal. */
3084 if (code->block == NULL)
3085 body = build_empty_stmt (input_location);
3087 /* Select the correct translation function. */
3088 else
3089 switch (code->expr1->ts.type)
3091 case BT_LOGICAL:
3092 body = gfc_trans_logical_select (code);
3093 break;
3095 case BT_INTEGER:
3096 body = gfc_trans_integer_select (code);
3097 break;
3099 case BT_CHARACTER:
3100 body = gfc_trans_character_select (code);
3101 break;
3103 default:
3104 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
3105 /* Not reached */
3108 /* Build everything together. */
3109 gfc_add_expr_to_block (&block, body);
3110 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3112 return gfc_finish_block (&block);
3115 tree
3116 gfc_trans_select_type (gfc_code * code)
3118 stmtblock_t block;
3119 tree body;
3120 tree exit_label;
3122 gcc_assert (code && code->expr1);
3123 gfc_init_block (&block);
3125 /* Build the exit label and hang it in. */
3126 exit_label = gfc_build_label_decl (NULL_TREE);
3127 code->exit_label = exit_label;
3129 /* Empty SELECT constructs are legal. */
3130 if (code->block == NULL)
3131 body = build_empty_stmt (input_location);
3132 else
3133 body = gfc_trans_select_type_cases (code);
3135 /* Build everything together. */
3136 gfc_add_expr_to_block (&block, body);
3138 if (TREE_USED (exit_label))
3139 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
3141 return gfc_finish_block (&block);
3145 /* Traversal function to substitute a replacement symtree if the symbol
3146 in the expression is the same as that passed. f == 2 signals that
3147 that variable itself is not to be checked - only the references.
3148 This group of functions is used when the variable expression in a
3149 FORALL assignment has internal references. For example:
3150 FORALL (i = 1:4) p(p(i)) = i
3151 The only recourse here is to store a copy of 'p' for the index
3152 expression. */
3154 static gfc_symtree *new_symtree;
3155 static gfc_symtree *old_symtree;
3157 static bool
3158 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
3160 if (expr->expr_type != EXPR_VARIABLE)
3161 return false;
3163 if (*f == 2)
3164 *f = 1;
3165 else if (expr->symtree->n.sym == sym)
3166 expr->symtree = new_symtree;
3168 return false;
3171 static void
3172 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
3174 gfc_traverse_expr (e, sym, forall_replace, f);
3177 static bool
3178 forall_restore (gfc_expr *expr,
3179 gfc_symbol *sym ATTRIBUTE_UNUSED,
3180 int *f ATTRIBUTE_UNUSED)
3182 if (expr->expr_type != EXPR_VARIABLE)
3183 return false;
3185 if (expr->symtree == new_symtree)
3186 expr->symtree = old_symtree;
3188 return false;
3191 static void
3192 forall_restore_symtree (gfc_expr *e)
3194 gfc_traverse_expr (e, NULL, forall_restore, 0);
3197 static void
3198 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3200 gfc_se tse;
3201 gfc_se rse;
3202 gfc_expr *e;
3203 gfc_symbol *new_sym;
3204 gfc_symbol *old_sym;
3205 gfc_symtree *root;
3206 tree tmp;
3208 /* Build a copy of the lvalue. */
3209 old_symtree = c->expr1->symtree;
3210 old_sym = old_symtree->n.sym;
3211 e = gfc_lval_expr_from_sym (old_sym);
3212 if (old_sym->attr.dimension)
3214 gfc_init_se (&tse, NULL);
3215 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
3216 gfc_add_block_to_block (pre, &tse.pre);
3217 gfc_add_block_to_block (post, &tse.post);
3218 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
3220 if (c->expr1->ref->u.ar.type != AR_SECTION)
3222 /* Use the variable offset for the temporary. */
3223 tmp = gfc_conv_array_offset (old_sym->backend_decl);
3224 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
3227 else
3229 gfc_init_se (&tse, NULL);
3230 gfc_init_se (&rse, NULL);
3231 gfc_conv_expr (&rse, e);
3232 if (e->ts.type == BT_CHARACTER)
3234 tse.string_length = rse.string_length;
3235 tmp = gfc_get_character_type_len (gfc_default_character_kind,
3236 tse.string_length);
3237 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
3238 rse.string_length);
3239 gfc_add_block_to_block (pre, &tse.pre);
3240 gfc_add_block_to_block (post, &tse.post);
3242 else
3244 tmp = gfc_typenode_for_spec (&e->ts);
3245 tse.expr = gfc_create_var (tmp, "temp");
3248 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts,
3249 e->expr_type == EXPR_VARIABLE, false);
3250 gfc_add_expr_to_block (pre, tmp);
3252 gfc_free_expr (e);
3254 /* Create a new symbol to represent the lvalue. */
3255 new_sym = gfc_new_symbol (old_sym->name, NULL);
3256 new_sym->ts = old_sym->ts;
3257 new_sym->attr.referenced = 1;
3258 new_sym->attr.temporary = 1;
3259 new_sym->attr.dimension = old_sym->attr.dimension;
3260 new_sym->attr.flavor = old_sym->attr.flavor;
3262 /* Use the temporary as the backend_decl. */
3263 new_sym->backend_decl = tse.expr;
3265 /* Create a fake symtree for it. */
3266 root = NULL;
3267 new_symtree = gfc_new_symtree (&root, old_sym->name);
3268 new_symtree->n.sym = new_sym;
3269 gcc_assert (new_symtree == root);
3271 /* Go through the expression reference replacing the old_symtree
3272 with the new. */
3273 forall_replace_symtree (c->expr1, old_sym, 2);
3275 /* Now we have made this temporary, we might as well use it for
3276 the right hand side. */
3277 forall_replace_symtree (c->expr2, old_sym, 1);
3281 /* Handles dependencies in forall assignments. */
3282 static int
3283 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
3285 gfc_ref *lref;
3286 gfc_ref *rref;
3287 int need_temp;
3288 gfc_symbol *lsym;
3290 lsym = c->expr1->symtree->n.sym;
3291 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
3293 /* Now check for dependencies within the 'variable'
3294 expression itself. These are treated by making a complete
3295 copy of variable and changing all the references to it
3296 point to the copy instead. Note that the shallow copy of
3297 the variable will not suffice for derived types with
3298 pointer components. We therefore leave these to their
3299 own devices. */
3300 if (lsym->ts.type == BT_DERIVED
3301 && lsym->ts.u.derived->attr.pointer_comp)
3302 return need_temp;
3304 new_symtree = NULL;
3305 if (find_forall_index (c->expr1, lsym, 2))
3307 forall_make_variable_temp (c, pre, post);
3308 need_temp = 0;
3311 /* Substrings with dependencies are treated in the same
3312 way. */
3313 if (c->expr1->ts.type == BT_CHARACTER
3314 && c->expr1->ref
3315 && c->expr2->expr_type == EXPR_VARIABLE
3316 && lsym == c->expr2->symtree->n.sym)
3318 for (lref = c->expr1->ref; lref; lref = lref->next)
3319 if (lref->type == REF_SUBSTRING)
3320 break;
3321 for (rref = c->expr2->ref; rref; rref = rref->next)
3322 if (rref->type == REF_SUBSTRING)
3323 break;
3325 if (rref && lref
3326 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
3328 forall_make_variable_temp (c, pre, post);
3329 need_temp = 0;
3332 return need_temp;
3336 static void
3337 cleanup_forall_symtrees (gfc_code *c)
3339 forall_restore_symtree (c->expr1);
3340 forall_restore_symtree (c->expr2);
3341 free (new_symtree->n.sym);
3342 free (new_symtree);
3346 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
3347 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
3348 indicates whether we should generate code to test the FORALLs mask
3349 array. OUTER is the loop header to be used for initializing mask
3350 indices.
3352 The generated loop format is:
3353 count = (end - start + step) / step
3354 loopvar = start
3355 while (1)
3357 if (count <=0 )
3358 goto end_of_loop
3359 <body>
3360 loopvar += step
3361 count --
3363 end_of_loop: */
3365 static tree
3366 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
3367 int mask_flag, stmtblock_t *outer)
3369 int n, nvar;
3370 tree tmp;
3371 tree cond;
3372 stmtblock_t block;
3373 tree exit_label;
3374 tree count;
3375 tree var, start, end, step;
3376 iter_info *iter;
3378 /* Initialize the mask index outside the FORALL nest. */
3379 if (mask_flag && forall_tmp->mask)
3380 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
3382 iter = forall_tmp->this_loop;
3383 nvar = forall_tmp->nvar;
3384 for (n = 0; n < nvar; n++)
3386 var = iter->var;
3387 start = iter->start;
3388 end = iter->end;
3389 step = iter->step;
3391 exit_label = gfc_build_label_decl (NULL_TREE);
3392 TREE_USED (exit_label) = 1;
3394 /* The loop counter. */
3395 count = gfc_create_var (TREE_TYPE (var), "count");
3397 /* The body of the loop. */
3398 gfc_init_block (&block);
3400 /* The exit condition. */
3401 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3402 count, build_int_cst (TREE_TYPE (count), 0));
3403 if (forall_tmp->do_concurrent)
3404 cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3405 build_int_cst (integer_type_node,
3406 annot_expr_ivdep_kind));
3408 tmp = build1_v (GOTO_EXPR, exit_label);
3409 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3410 cond, tmp, build_empty_stmt (input_location));
3411 gfc_add_expr_to_block (&block, tmp);
3413 /* The main loop body. */
3414 gfc_add_expr_to_block (&block, body);
3416 /* Increment the loop variable. */
3417 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3418 step);
3419 gfc_add_modify (&block, var, tmp);
3421 /* Advance to the next mask element. Only do this for the
3422 innermost loop. */
3423 if (n == 0 && mask_flag && forall_tmp->mask)
3425 tree maskindex = forall_tmp->maskindex;
3426 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3427 maskindex, gfc_index_one_node);
3428 gfc_add_modify (&block, maskindex, tmp);
3431 /* Decrement the loop counter. */
3432 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3433 build_int_cst (TREE_TYPE (var), 1));
3434 gfc_add_modify (&block, count, tmp);
3436 body = gfc_finish_block (&block);
3438 /* Loop var initialization. */
3439 gfc_init_block (&block);
3440 gfc_add_modify (&block, var, start);
3443 /* Initialize the loop counter. */
3444 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3445 start);
3446 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3447 tmp);
3448 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3449 tmp, step);
3450 gfc_add_modify (&block, count, tmp);
3452 /* The loop expression. */
3453 tmp = build1_v (LOOP_EXPR, body);
3454 gfc_add_expr_to_block (&block, tmp);
3456 /* The exit label. */
3457 tmp = build1_v (LABEL_EXPR, exit_label);
3458 gfc_add_expr_to_block (&block, tmp);
3460 body = gfc_finish_block (&block);
3461 iter = iter->next;
3463 return body;
3467 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3468 is nonzero, the body is controlled by all masks in the forall nest.
3469 Otherwise, the innermost loop is not controlled by it's mask. This
3470 is used for initializing that mask. */
3472 static tree
3473 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3474 int mask_flag)
3476 tree tmp;
3477 stmtblock_t header;
3478 forall_info *forall_tmp;
3479 tree mask, maskindex;
3481 gfc_start_block (&header);
3483 forall_tmp = nested_forall_info;
3484 while (forall_tmp != NULL)
3486 /* Generate body with masks' control. */
3487 if (mask_flag)
3489 mask = forall_tmp->mask;
3490 maskindex = forall_tmp->maskindex;
3492 /* If a mask was specified make the assignment conditional. */
3493 if (mask)
3495 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3496 body = build3_v (COND_EXPR, tmp, body,
3497 build_empty_stmt (input_location));
3500 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3501 forall_tmp = forall_tmp->prev_nest;
3502 mask_flag = 1;
3505 gfc_add_expr_to_block (&header, body);
3506 return gfc_finish_block (&header);
3510 /* Allocate data for holding a temporary array. Returns either a local
3511 temporary array or a pointer variable. */
3513 static tree
3514 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3515 tree elem_type)
3517 tree tmpvar;
3518 tree type;
3519 tree tmp;
3521 if (INTEGER_CST_P (size))
3522 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3523 size, gfc_index_one_node);
3524 else
3525 tmp = NULL_TREE;
3527 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3528 type = build_array_type (elem_type, type);
3529 if (gfc_can_put_var_on_stack (bytesize) && INTEGER_CST_P (size))
3531 tmpvar = gfc_create_var (type, "temp");
3532 *pdata = NULL_TREE;
3534 else
3536 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3537 *pdata = convert (pvoid_type_node, tmpvar);
3539 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3540 gfc_add_modify (pblock, tmpvar, tmp);
3542 return tmpvar;
3546 /* Generate codes to copy the temporary to the actual lhs. */
3548 static tree
3549 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3550 tree count1,
3551 gfc_ss *lss, gfc_ss *rss,
3552 tree wheremask, bool invert)
3554 stmtblock_t block, body1;
3555 gfc_loopinfo loop;
3556 gfc_se lse;
3557 gfc_se rse;
3558 tree tmp;
3559 tree wheremaskexpr;
3561 (void) rss; /* TODO: unused. */
3563 gfc_start_block (&block);
3565 gfc_init_se (&rse, NULL);
3566 gfc_init_se (&lse, NULL);
3568 if (lss == gfc_ss_terminator)
3570 gfc_init_block (&body1);
3571 gfc_conv_expr (&lse, expr);
3572 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3574 else
3576 /* Initialize the loop. */
3577 gfc_init_loopinfo (&loop);
3579 /* We may need LSS to determine the shape of the expression. */
3580 gfc_add_ss_to_loop (&loop, lss);
3582 gfc_conv_ss_startstride (&loop);
3583 gfc_conv_loop_setup (&loop, &expr->where);
3585 gfc_mark_ss_chain_used (lss, 1);
3586 /* Start the loop body. */
3587 gfc_start_scalarized_body (&loop, &body1);
3589 /* Translate the expression. */
3590 gfc_copy_loopinfo_to_se (&lse, &loop);
3591 lse.ss = lss;
3592 gfc_conv_expr (&lse, expr);
3594 /* Form the expression of the temporary. */
3595 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3598 /* Use the scalar assignment. */
3599 rse.string_length = lse.string_length;
3600 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts,
3601 expr->expr_type == EXPR_VARIABLE, false);
3603 /* Form the mask expression according to the mask tree list. */
3604 if (wheremask)
3606 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3607 if (invert)
3608 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3609 TREE_TYPE (wheremaskexpr),
3610 wheremaskexpr);
3611 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3612 wheremaskexpr, tmp,
3613 build_empty_stmt (input_location));
3616 gfc_add_expr_to_block (&body1, tmp);
3618 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3619 count1, gfc_index_one_node);
3620 gfc_add_modify (&body1, count1, tmp);
3622 if (lss == gfc_ss_terminator)
3623 gfc_add_block_to_block (&block, &body1);
3624 else
3626 /* Increment count3. */
3627 if (count3)
3629 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3630 gfc_array_index_type,
3631 count3, gfc_index_one_node);
3632 gfc_add_modify (&body1, count3, tmp);
3635 /* Generate the copying loops. */
3636 gfc_trans_scalarizing_loops (&loop, &body1);
3638 gfc_add_block_to_block (&block, &loop.pre);
3639 gfc_add_block_to_block (&block, &loop.post);
3641 gfc_cleanup_loop (&loop);
3642 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3643 as tree nodes in SS may not be valid in different scope. */
3646 tmp = gfc_finish_block (&block);
3647 return tmp;
3651 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3652 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3653 and should not be freed. WHEREMASK is the conditional execution mask
3654 whose sense may be inverted by INVERT. */
3656 static tree
3657 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3658 tree count1, gfc_ss *lss, gfc_ss *rss,
3659 tree wheremask, bool invert)
3661 stmtblock_t block, body1;
3662 gfc_loopinfo loop;
3663 gfc_se lse;
3664 gfc_se rse;
3665 tree tmp;
3666 tree wheremaskexpr;
3668 gfc_start_block (&block);
3670 gfc_init_se (&rse, NULL);
3671 gfc_init_se (&lse, NULL);
3673 if (lss == gfc_ss_terminator)
3675 gfc_init_block (&body1);
3676 gfc_conv_expr (&rse, expr2);
3677 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3679 else
3681 /* Initialize the loop. */
3682 gfc_init_loopinfo (&loop);
3684 /* We may need LSS to determine the shape of the expression. */
3685 gfc_add_ss_to_loop (&loop, lss);
3686 gfc_add_ss_to_loop (&loop, rss);
3688 gfc_conv_ss_startstride (&loop);
3689 gfc_conv_loop_setup (&loop, &expr2->where);
3691 gfc_mark_ss_chain_used (rss, 1);
3692 /* Start the loop body. */
3693 gfc_start_scalarized_body (&loop, &body1);
3695 /* Translate the expression. */
3696 gfc_copy_loopinfo_to_se (&rse, &loop);
3697 rse.ss = rss;
3698 gfc_conv_expr (&rse, expr2);
3700 /* Form the expression of the temporary. */
3701 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3704 /* Use the scalar assignment. */
3705 lse.string_length = rse.string_length;
3706 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts,
3707 expr2->expr_type == EXPR_VARIABLE, false);
3709 /* Form the mask expression according to the mask tree list. */
3710 if (wheremask)
3712 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3713 if (invert)
3714 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3715 TREE_TYPE (wheremaskexpr),
3716 wheremaskexpr);
3717 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3718 wheremaskexpr, tmp,
3719 build_empty_stmt (input_location));
3722 gfc_add_expr_to_block (&body1, tmp);
3724 if (lss == gfc_ss_terminator)
3726 gfc_add_block_to_block (&block, &body1);
3728 /* Increment count1. */
3729 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3730 count1, gfc_index_one_node);
3731 gfc_add_modify (&block, count1, tmp);
3733 else
3735 /* Increment count1. */
3736 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3737 count1, gfc_index_one_node);
3738 gfc_add_modify (&body1, count1, tmp);
3740 /* Increment count3. */
3741 if (count3)
3743 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3744 gfc_array_index_type,
3745 count3, gfc_index_one_node);
3746 gfc_add_modify (&body1, count3, tmp);
3749 /* Generate the copying loops. */
3750 gfc_trans_scalarizing_loops (&loop, &body1);
3752 gfc_add_block_to_block (&block, &loop.pre);
3753 gfc_add_block_to_block (&block, &loop.post);
3755 gfc_cleanup_loop (&loop);
3756 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3757 as tree nodes in SS may not be valid in different scope. */
3760 tmp = gfc_finish_block (&block);
3761 return tmp;
3765 /* Calculate the size of temporary needed in the assignment inside forall.
3766 LSS and RSS are filled in this function. */
3768 static tree
3769 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3770 stmtblock_t * pblock,
3771 gfc_ss **lss, gfc_ss **rss)
3773 gfc_loopinfo loop;
3774 tree size;
3775 int i;
3776 int save_flag;
3777 tree tmp;
3779 *lss = gfc_walk_expr (expr1);
3780 *rss = NULL;
3782 size = gfc_index_one_node;
3783 if (*lss != gfc_ss_terminator)
3785 gfc_init_loopinfo (&loop);
3787 /* Walk the RHS of the expression. */
3788 *rss = gfc_walk_expr (expr2);
3789 if (*rss == gfc_ss_terminator)
3790 /* The rhs is scalar. Add a ss for the expression. */
3791 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3793 /* Associate the SS with the loop. */
3794 gfc_add_ss_to_loop (&loop, *lss);
3795 /* We don't actually need to add the rhs at this point, but it might
3796 make guessing the loop bounds a bit easier. */
3797 gfc_add_ss_to_loop (&loop, *rss);
3799 /* We only want the shape of the expression, not rest of the junk
3800 generated by the scalarizer. */
3801 loop.array_parameter = 1;
3803 /* Calculate the bounds of the scalarization. */
3804 save_flag = gfc_option.rtcheck;
3805 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3806 gfc_conv_ss_startstride (&loop);
3807 gfc_option.rtcheck = save_flag;
3808 gfc_conv_loop_setup (&loop, &expr2->where);
3810 /* Figure out how many elements we need. */
3811 for (i = 0; i < loop.dimen; i++)
3813 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3814 gfc_array_index_type,
3815 gfc_index_one_node, loop.from[i]);
3816 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3817 gfc_array_index_type, tmp, loop.to[i]);
3818 size = fold_build2_loc (input_location, MULT_EXPR,
3819 gfc_array_index_type, size, tmp);
3821 gfc_add_block_to_block (pblock, &loop.pre);
3822 size = gfc_evaluate_now (size, pblock);
3823 gfc_add_block_to_block (pblock, &loop.post);
3825 /* TODO: write a function that cleans up a loopinfo without freeing
3826 the SS chains. Currently a NOP. */
3829 return size;
3833 /* Calculate the overall iterator number of the nested forall construct.
3834 This routine actually calculates the number of times the body of the
3835 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3836 that by the expression INNER_SIZE. The BLOCK argument specifies the
3837 block in which to calculate the result, and the optional INNER_SIZE_BODY
3838 argument contains any statements that need to executed (inside the loop)
3839 to initialize or calculate INNER_SIZE. */
3841 static tree
3842 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3843 stmtblock_t *inner_size_body, stmtblock_t *block)
3845 forall_info *forall_tmp = nested_forall_info;
3846 tree tmp, number;
3847 stmtblock_t body;
3849 /* We can eliminate the innermost unconditional loops with constant
3850 array bounds. */
3851 if (INTEGER_CST_P (inner_size))
3853 while (forall_tmp
3854 && !forall_tmp->mask
3855 && INTEGER_CST_P (forall_tmp->size))
3857 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3858 gfc_array_index_type,
3859 inner_size, forall_tmp->size);
3860 forall_tmp = forall_tmp->prev_nest;
3863 /* If there are no loops left, we have our constant result. */
3864 if (!forall_tmp)
3865 return inner_size;
3868 /* Otherwise, create a temporary variable to compute the result. */
3869 number = gfc_create_var (gfc_array_index_type, "num");
3870 gfc_add_modify (block, number, gfc_index_zero_node);
3872 gfc_start_block (&body);
3873 if (inner_size_body)
3874 gfc_add_block_to_block (&body, inner_size_body);
3875 if (forall_tmp)
3876 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3877 gfc_array_index_type, number, inner_size);
3878 else
3879 tmp = inner_size;
3880 gfc_add_modify (&body, number, tmp);
3881 tmp = gfc_finish_block (&body);
3883 /* Generate loops. */
3884 if (forall_tmp != NULL)
3885 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3887 gfc_add_expr_to_block (block, tmp);
3889 return number;
3893 /* Allocate temporary for forall construct. SIZE is the size of temporary
3894 needed. PTEMP1 is returned for space free. */
3896 static tree
3897 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3898 tree * ptemp1)
3900 tree bytesize;
3901 tree unit;
3902 tree tmp;
3904 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3905 if (!integer_onep (unit))
3906 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3907 gfc_array_index_type, size, unit);
3908 else
3909 bytesize = size;
3911 *ptemp1 = NULL;
3912 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3914 if (*ptemp1)
3915 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3916 return tmp;
3920 /* Allocate temporary for forall construct according to the information in
3921 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3922 assignment inside forall. PTEMP1 is returned for space free. */
3924 static tree
3925 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3926 tree inner_size, stmtblock_t * inner_size_body,
3927 stmtblock_t * block, tree * ptemp1)
3929 tree size;
3931 /* Calculate the total size of temporary needed in forall construct. */
3932 size = compute_overall_iter_number (nested_forall_info, inner_size,
3933 inner_size_body, block);
3935 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3939 /* Handle assignments inside forall which need temporary.
3941 forall (i=start:end:stride; maskexpr)
3942 e<i> = f<i>
3943 end forall
3944 (where e,f<i> are arbitrary expressions possibly involving i
3945 and there is a dependency between e<i> and f<i>)
3946 Translates to:
3947 masktmp(:) = maskexpr(:)
3949 maskindex = 0;
3950 count1 = 0;
3951 num = 0;
3952 for (i = start; i <= end; i += stride)
3953 num += SIZE (f<i>)
3954 count1 = 0;
3955 ALLOCATE (tmp(num))
3956 for (i = start; i <= end; i += stride)
3958 if (masktmp[maskindex++])
3959 tmp[count1++] = f<i>
3961 maskindex = 0;
3962 count1 = 0;
3963 for (i = start; i <= end; i += stride)
3965 if (masktmp[maskindex++])
3966 e<i> = tmp[count1++]
3968 DEALLOCATE (tmp)
3970 static void
3971 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3972 tree wheremask, bool invert,
3973 forall_info * nested_forall_info,
3974 stmtblock_t * block)
3976 tree type;
3977 tree inner_size;
3978 gfc_ss *lss, *rss;
3979 tree count, count1;
3980 tree tmp, tmp1;
3981 tree ptemp1;
3982 stmtblock_t inner_size_body;
3984 /* Create vars. count1 is the current iterator number of the nested
3985 forall. */
3986 count1 = gfc_create_var (gfc_array_index_type, "count1");
3988 /* Count is the wheremask index. */
3989 if (wheremask)
3991 count = gfc_create_var (gfc_array_index_type, "count");
3992 gfc_add_modify (block, count, gfc_index_zero_node);
3994 else
3995 count = NULL;
3997 /* Initialize count1. */
3998 gfc_add_modify (block, count1, gfc_index_zero_node);
4000 /* Calculate the size of temporary needed in the assignment. Return loop, lss
4001 and rss which are used in function generate_loop_for_rhs_to_temp(). */
4002 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
4003 if (expr1->ts.type == BT_CHARACTER)
4005 type = NULL;
4006 if (expr1->ref && expr1->ref->type == REF_SUBSTRING)
4008 gfc_se ssse;
4009 gfc_init_se (&ssse, NULL);
4010 gfc_conv_expr (&ssse, expr1);
4011 type = gfc_get_character_type_len (gfc_default_character_kind,
4012 ssse.string_length);
4014 else
4016 if (!expr1->ts.u.cl->backend_decl)
4018 gfc_se tse;
4019 gcc_assert (expr1->ts.u.cl->length);
4020 gfc_init_se (&tse, NULL);
4021 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
4022 expr1->ts.u.cl->backend_decl = tse.expr;
4024 type = gfc_get_character_type_len (gfc_default_character_kind,
4025 expr1->ts.u.cl->backend_decl);
4028 else
4029 type = gfc_typenode_for_spec (&expr1->ts);
4031 gfc_init_block (&inner_size_body);
4032 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4033 &lss, &rss);
4035 /* Allocate temporary for nested forall construct according to the
4036 information in nested_forall_info and inner_size. */
4037 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
4038 &inner_size_body, block, &ptemp1);
4040 /* Generate codes to copy rhs to the temporary . */
4041 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
4042 wheremask, invert);
4044 /* Generate body and loops according to the information in
4045 nested_forall_info. */
4046 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4047 gfc_add_expr_to_block (block, tmp);
4049 /* Reset count1. */
4050 gfc_add_modify (block, count1, gfc_index_zero_node);
4052 /* Reset count. */
4053 if (wheremask)
4054 gfc_add_modify (block, count, gfc_index_zero_node);
4056 /* TODO: Second call to compute_inner_temp_size to initialize lss and
4057 rss; there must be a better way. */
4058 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
4059 &lss, &rss);
4061 /* Generate codes to copy the temporary to lhs. */
4062 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
4063 lss, rss,
4064 wheremask, invert);
4066 /* Generate body and loops according to the information in
4067 nested_forall_info. */
4068 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4069 gfc_add_expr_to_block (block, tmp);
4071 if (ptemp1)
4073 /* Free the temporary. */
4074 tmp = gfc_call_free (ptemp1);
4075 gfc_add_expr_to_block (block, tmp);
4080 /* Translate pointer assignment inside FORALL which need temporary. */
4082 static void
4083 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
4084 forall_info * nested_forall_info,
4085 stmtblock_t * block)
4087 tree type;
4088 tree inner_size;
4089 gfc_ss *lss, *rss;
4090 gfc_se lse;
4091 gfc_se rse;
4092 gfc_array_info *info;
4093 gfc_loopinfo loop;
4094 tree desc;
4095 tree parm;
4096 tree parmtype;
4097 stmtblock_t body;
4098 tree count;
4099 tree tmp, tmp1, ptemp1;
4101 count = gfc_create_var (gfc_array_index_type, "count");
4102 gfc_add_modify (block, count, gfc_index_zero_node);
4104 inner_size = gfc_index_one_node;
4105 lss = gfc_walk_expr (expr1);
4106 rss = gfc_walk_expr (expr2);
4107 if (lss == gfc_ss_terminator)
4109 type = gfc_typenode_for_spec (&expr1->ts);
4110 type = build_pointer_type (type);
4112 /* Allocate temporary for nested forall construct according to the
4113 information in nested_forall_info and inner_size. */
4114 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
4115 inner_size, NULL, block, &ptemp1);
4116 gfc_start_block (&body);
4117 gfc_init_se (&lse, NULL);
4118 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4119 gfc_init_se (&rse, NULL);
4120 rse.want_pointer = 1;
4121 gfc_conv_expr (&rse, expr2);
4122 gfc_add_block_to_block (&body, &rse.pre);
4123 gfc_add_modify (&body, lse.expr,
4124 fold_convert (TREE_TYPE (lse.expr), rse.expr));
4125 gfc_add_block_to_block (&body, &rse.post);
4127 /* Increment count. */
4128 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4129 count, gfc_index_one_node);
4130 gfc_add_modify (&body, count, tmp);
4132 tmp = gfc_finish_block (&body);
4134 /* Generate body and loops according to the information in
4135 nested_forall_info. */
4136 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4137 gfc_add_expr_to_block (block, tmp);
4139 /* Reset count. */
4140 gfc_add_modify (block, count, gfc_index_zero_node);
4142 gfc_start_block (&body);
4143 gfc_init_se (&lse, NULL);
4144 gfc_init_se (&rse, NULL);
4145 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
4146 lse.want_pointer = 1;
4147 gfc_conv_expr (&lse, expr1);
4148 gfc_add_block_to_block (&body, &lse.pre);
4149 gfc_add_modify (&body, lse.expr, rse.expr);
4150 gfc_add_block_to_block (&body, &lse.post);
4151 /* Increment count. */
4152 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4153 count, gfc_index_one_node);
4154 gfc_add_modify (&body, count, tmp);
4155 tmp = gfc_finish_block (&body);
4157 /* Generate body and loops according to the information in
4158 nested_forall_info. */
4159 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4160 gfc_add_expr_to_block (block, tmp);
4162 else
4164 gfc_init_loopinfo (&loop);
4166 /* Associate the SS with the loop. */
4167 gfc_add_ss_to_loop (&loop, rss);
4169 /* Setup the scalarizing loops and bounds. */
4170 gfc_conv_ss_startstride (&loop);
4172 gfc_conv_loop_setup (&loop, &expr2->where);
4174 info = &rss->info->data.array;
4175 desc = info->descriptor;
4177 /* Make a new descriptor. */
4178 parmtype = gfc_get_element_type (TREE_TYPE (desc));
4179 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
4180 loop.from, loop.to, 1,
4181 GFC_ARRAY_UNKNOWN, true);
4183 /* Allocate temporary for nested forall construct. */
4184 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
4185 inner_size, NULL, block, &ptemp1);
4186 gfc_start_block (&body);
4187 gfc_init_se (&lse, NULL);
4188 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
4189 lse.direct_byref = 1;
4190 gfc_conv_expr_descriptor (&lse, expr2);
4192 gfc_add_block_to_block (&body, &lse.pre);
4193 gfc_add_block_to_block (&body, &lse.post);
4195 /* Increment count. */
4196 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4197 count, gfc_index_one_node);
4198 gfc_add_modify (&body, count, tmp);
4200 tmp = gfc_finish_block (&body);
4202 /* Generate body and loops according to the information in
4203 nested_forall_info. */
4204 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4205 gfc_add_expr_to_block (block, tmp);
4207 /* Reset count. */
4208 gfc_add_modify (block, count, gfc_index_zero_node);
4210 parm = gfc_build_array_ref (tmp1, count, NULL);
4211 gfc_init_se (&lse, NULL);
4212 gfc_conv_expr_descriptor (&lse, expr1);
4213 gfc_add_modify (&lse.pre, lse.expr, parm);
4214 gfc_start_block (&body);
4215 gfc_add_block_to_block (&body, &lse.pre);
4216 gfc_add_block_to_block (&body, &lse.post);
4218 /* Increment count. */
4219 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4220 count, gfc_index_one_node);
4221 gfc_add_modify (&body, count, tmp);
4223 tmp = gfc_finish_block (&body);
4225 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4226 gfc_add_expr_to_block (block, tmp);
4228 /* Free the temporary. */
4229 if (ptemp1)
4231 tmp = gfc_call_free (ptemp1);
4232 gfc_add_expr_to_block (block, tmp);
4237 /* FORALL and WHERE statements are really nasty, especially when you nest
4238 them. All the rhs of a forall assignment must be evaluated before the
4239 actual assignments are performed. Presumably this also applies to all the
4240 assignments in an inner where statement. */
4242 /* Generate code for a FORALL statement. Any temporaries are allocated as a
4243 linear array, relying on the fact that we process in the same order in all
4244 loops.
4246 forall (i=start:end:stride; maskexpr)
4247 e<i> = f<i>
4248 g<i> = h<i>
4249 end forall
4250 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
4251 Translates to:
4252 count = ((end + 1 - start) / stride)
4253 masktmp(:) = maskexpr(:)
4255 maskindex = 0;
4256 for (i = start; i <= end; i += stride)
4258 if (masktmp[maskindex++])
4259 e<i> = f<i>
4261 maskindex = 0;
4262 for (i = start; i <= end; i += stride)
4264 if (masktmp[maskindex++])
4265 g<i> = h<i>
4268 Note that this code only works when there are no dependencies.
4269 Forall loop with array assignments and data dependencies are a real pain,
4270 because the size of the temporary cannot always be determined before the
4271 loop is executed. This problem is compounded by the presence of nested
4272 FORALL constructs.
4275 static tree
4276 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
4278 stmtblock_t pre;
4279 stmtblock_t post;
4280 stmtblock_t block;
4281 stmtblock_t body;
4282 tree *var;
4283 tree *start;
4284 tree *end;
4285 tree *step;
4286 gfc_expr **varexpr;
4287 tree tmp;
4288 tree assign;
4289 tree size;
4290 tree maskindex;
4291 tree mask;
4292 tree pmask;
4293 tree cycle_label = NULL_TREE;
4294 int n;
4295 int nvar;
4296 int need_temp;
4297 gfc_forall_iterator *fa;
4298 gfc_se se;
4299 gfc_code *c;
4300 gfc_saved_var *saved_vars;
4301 iter_info *this_forall;
4302 forall_info *info;
4303 bool need_mask;
4305 /* Do nothing if the mask is false. */
4306 if (code->expr1
4307 && code->expr1->expr_type == EXPR_CONSTANT
4308 && !code->expr1->value.logical)
4309 return build_empty_stmt (input_location);
4311 n = 0;
4312 /* Count the FORALL index number. */
4313 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4314 n++;
4315 nvar = n;
4317 /* Allocate the space for var, start, end, step, varexpr. */
4318 var = XCNEWVEC (tree, nvar);
4319 start = XCNEWVEC (tree, nvar);
4320 end = XCNEWVEC (tree, nvar);
4321 step = XCNEWVEC (tree, nvar);
4322 varexpr = XCNEWVEC (gfc_expr *, nvar);
4323 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
4325 /* Allocate the space for info. */
4326 info = XCNEW (forall_info);
4328 gfc_start_block (&pre);
4329 gfc_init_block (&post);
4330 gfc_init_block (&block);
4332 n = 0;
4333 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
4335 gfc_symbol *sym = fa->var->symtree->n.sym;
4337 /* Allocate space for this_forall. */
4338 this_forall = XCNEW (iter_info);
4340 /* Create a temporary variable for the FORALL index. */
4341 tmp = gfc_typenode_for_spec (&sym->ts);
4342 var[n] = gfc_create_var (tmp, sym->name);
4343 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
4345 /* Record it in this_forall. */
4346 this_forall->var = var[n];
4348 /* Replace the index symbol's backend_decl with the temporary decl. */
4349 sym->backend_decl = var[n];
4351 /* Work out the start, end and stride for the loop. */
4352 gfc_init_se (&se, NULL);
4353 gfc_conv_expr_val (&se, fa->start);
4354 /* Record it in this_forall. */
4355 this_forall->start = se.expr;
4356 gfc_add_block_to_block (&block, &se.pre);
4357 start[n] = se.expr;
4359 gfc_init_se (&se, NULL);
4360 gfc_conv_expr_val (&se, fa->end);
4361 /* Record it in this_forall. */
4362 this_forall->end = se.expr;
4363 gfc_make_safe_expr (&se);
4364 gfc_add_block_to_block (&block, &se.pre);
4365 end[n] = se.expr;
4367 gfc_init_se (&se, NULL);
4368 gfc_conv_expr_val (&se, fa->stride);
4369 /* Record it in this_forall. */
4370 this_forall->step = se.expr;
4371 gfc_make_safe_expr (&se);
4372 gfc_add_block_to_block (&block, &se.pre);
4373 step[n] = se.expr;
4375 /* Set the NEXT field of this_forall to NULL. */
4376 this_forall->next = NULL;
4377 /* Link this_forall to the info construct. */
4378 if (info->this_loop)
4380 iter_info *iter_tmp = info->this_loop;
4381 while (iter_tmp->next != NULL)
4382 iter_tmp = iter_tmp->next;
4383 iter_tmp->next = this_forall;
4385 else
4386 info->this_loop = this_forall;
4388 n++;
4390 nvar = n;
4392 /* Calculate the size needed for the current forall level. */
4393 size = gfc_index_one_node;
4394 for (n = 0; n < nvar; n++)
4396 /* size = (end + step - start) / step. */
4397 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4398 step[n], start[n]);
4399 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4400 end[n], tmp);
4401 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4402 tmp, step[n]);
4403 tmp = convert (gfc_array_index_type, tmp);
4405 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4406 size, tmp);
4409 /* Record the nvar and size of current forall level. */
4410 info->nvar = nvar;
4411 info->size = size;
4413 if (code->expr1)
4415 /* If the mask is .true., consider the FORALL unconditional. */
4416 if (code->expr1->expr_type == EXPR_CONSTANT
4417 && code->expr1->value.logical)
4418 need_mask = false;
4419 else
4420 need_mask = true;
4422 else
4423 need_mask = false;
4425 /* First we need to allocate the mask. */
4426 if (need_mask)
4428 /* As the mask array can be very big, prefer compact boolean types. */
4429 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4430 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4431 size, NULL, &block, &pmask);
4432 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4434 /* Record them in the info structure. */
4435 info->maskindex = maskindex;
4436 info->mask = mask;
4438 else
4440 /* No mask was specified. */
4441 maskindex = NULL_TREE;
4442 mask = pmask = NULL_TREE;
4445 /* Link the current forall level to nested_forall_info. */
4446 info->prev_nest = nested_forall_info;
4447 nested_forall_info = info;
4449 /* Copy the mask into a temporary variable if required.
4450 For now we assume a mask temporary is needed. */
4451 if (need_mask)
4453 /* As the mask array can be very big, prefer compact boolean types. */
4454 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4456 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4458 /* Start of mask assignment loop body. */
4459 gfc_start_block (&body);
4461 /* Evaluate the mask expression. */
4462 gfc_init_se (&se, NULL);
4463 gfc_conv_expr_val (&se, code->expr1);
4464 gfc_add_block_to_block (&body, &se.pre);
4466 /* Store the mask. */
4467 se.expr = convert (mask_type, se.expr);
4469 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4470 gfc_add_modify (&body, tmp, se.expr);
4472 /* Advance to the next mask element. */
4473 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4474 maskindex, gfc_index_one_node);
4475 gfc_add_modify (&body, maskindex, tmp);
4477 /* Generate the loops. */
4478 tmp = gfc_finish_block (&body);
4479 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4480 gfc_add_expr_to_block (&block, tmp);
4483 if (code->op == EXEC_DO_CONCURRENT)
4485 gfc_init_block (&body);
4486 cycle_label = gfc_build_label_decl (NULL_TREE);
4487 code->cycle_label = cycle_label;
4488 tmp = gfc_trans_code (code->block->next);
4489 gfc_add_expr_to_block (&body, tmp);
4491 if (TREE_USED (cycle_label))
4493 tmp = build1_v (LABEL_EXPR, cycle_label);
4494 gfc_add_expr_to_block (&body, tmp);
4497 tmp = gfc_finish_block (&body);
4498 nested_forall_info->do_concurrent = true;
4499 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4500 gfc_add_expr_to_block (&block, tmp);
4501 goto done;
4504 c = code->block->next;
4506 /* TODO: loop merging in FORALL statements. */
4507 /* Now that we've got a copy of the mask, generate the assignment loops. */
4508 while (c)
4510 switch (c->op)
4512 case EXEC_ASSIGN:
4513 /* A scalar or array assignment. DO the simple check for
4514 lhs to rhs dependencies. These make a temporary for the
4515 rhs and form a second forall block to copy to variable. */
4516 need_temp = check_forall_dependencies(c, &pre, &post);
4518 /* Temporaries due to array assignment data dependencies introduce
4519 no end of problems. */
4520 if (need_temp || flag_test_forall_temp)
4521 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4522 nested_forall_info, &block);
4523 else
4525 /* Use the normal assignment copying routines. */
4526 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4528 /* Generate body and loops. */
4529 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4530 assign, 1);
4531 gfc_add_expr_to_block (&block, tmp);
4534 /* Cleanup any temporary symtrees that have been made to deal
4535 with dependencies. */
4536 if (new_symtree)
4537 cleanup_forall_symtrees (c);
4539 break;
4541 case EXEC_WHERE:
4542 /* Translate WHERE or WHERE construct nested in FORALL. */
4543 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4544 break;
4546 /* Pointer assignment inside FORALL. */
4547 case EXEC_POINTER_ASSIGN:
4548 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4549 /* Avoid cases where a temporary would never be needed and where
4550 the temp code is guaranteed to fail. */
4551 if (need_temp
4552 || (flag_test_forall_temp
4553 && c->expr2->expr_type != EXPR_CONSTANT
4554 && c->expr2->expr_type != EXPR_NULL))
4555 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4556 nested_forall_info, &block);
4557 else
4559 /* Use the normal assignment copying routines. */
4560 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4562 /* Generate body and loops. */
4563 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4564 assign, 1);
4565 gfc_add_expr_to_block (&block, tmp);
4567 break;
4569 case EXEC_FORALL:
4570 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4571 gfc_add_expr_to_block (&block, tmp);
4572 break;
4574 /* Explicit subroutine calls are prevented by the frontend but interface
4575 assignments can legitimately produce them. */
4576 case EXEC_ASSIGN_CALL:
4577 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4578 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4579 gfc_add_expr_to_block (&block, tmp);
4580 break;
4582 default:
4583 gcc_unreachable ();
4586 c = c->next;
4589 done:
4590 /* Restore the original index variables. */
4591 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4592 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4594 /* Free the space for var, start, end, step, varexpr. */
4595 free (var);
4596 free (start);
4597 free (end);
4598 free (step);
4599 free (varexpr);
4600 free (saved_vars);
4602 for (this_forall = info->this_loop; this_forall;)
4604 iter_info *next = this_forall->next;
4605 free (this_forall);
4606 this_forall = next;
4609 /* Free the space for this forall_info. */
4610 free (info);
4612 if (pmask)
4614 /* Free the temporary for the mask. */
4615 tmp = gfc_call_free (pmask);
4616 gfc_add_expr_to_block (&block, tmp);
4618 if (maskindex)
4619 pushdecl (maskindex);
4621 gfc_add_block_to_block (&pre, &block);
4622 gfc_add_block_to_block (&pre, &post);
4624 return gfc_finish_block (&pre);
4628 /* Translate the FORALL statement or construct. */
4630 tree gfc_trans_forall (gfc_code * code)
4632 return gfc_trans_forall_1 (code, NULL);
4636 /* Translate the DO CONCURRENT construct. */
4638 tree gfc_trans_do_concurrent (gfc_code * code)
4640 return gfc_trans_forall_1 (code, NULL);
4644 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4645 If the WHERE construct is nested in FORALL, compute the overall temporary
4646 needed by the WHERE mask expression multiplied by the iterator number of
4647 the nested forall.
4648 ME is the WHERE mask expression.
4649 MASK is the current execution mask upon input, whose sense may or may
4650 not be inverted as specified by the INVERT argument.
4651 CMASK is the updated execution mask on output, or NULL if not required.
4652 PMASK is the pending execution mask on output, or NULL if not required.
4653 BLOCK is the block in which to place the condition evaluation loops. */
4655 static void
4656 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4657 tree mask, bool invert, tree cmask, tree pmask,
4658 tree mask_type, stmtblock_t * block)
4660 tree tmp, tmp1;
4661 gfc_ss *lss, *rss;
4662 gfc_loopinfo loop;
4663 stmtblock_t body, body1;
4664 tree count, cond, mtmp;
4665 gfc_se lse, rse;
4667 gfc_init_loopinfo (&loop);
4669 lss = gfc_walk_expr (me);
4670 rss = gfc_walk_expr (me);
4672 /* Variable to index the temporary. */
4673 count = gfc_create_var (gfc_array_index_type, "count");
4674 /* Initialize count. */
4675 gfc_add_modify (block, count, gfc_index_zero_node);
4677 gfc_start_block (&body);
4679 gfc_init_se (&rse, NULL);
4680 gfc_init_se (&lse, NULL);
4682 if (lss == gfc_ss_terminator)
4684 gfc_init_block (&body1);
4686 else
4688 /* Initialize the loop. */
4689 gfc_init_loopinfo (&loop);
4691 /* We may need LSS to determine the shape of the expression. */
4692 gfc_add_ss_to_loop (&loop, lss);
4693 gfc_add_ss_to_loop (&loop, rss);
4695 gfc_conv_ss_startstride (&loop);
4696 gfc_conv_loop_setup (&loop, &me->where);
4698 gfc_mark_ss_chain_used (rss, 1);
4699 /* Start the loop body. */
4700 gfc_start_scalarized_body (&loop, &body1);
4702 /* Translate the expression. */
4703 gfc_copy_loopinfo_to_se (&rse, &loop);
4704 rse.ss = rss;
4705 gfc_conv_expr (&rse, me);
4708 /* Variable to evaluate mask condition. */
4709 cond = gfc_create_var (mask_type, "cond");
4710 if (mask && (cmask || pmask))
4711 mtmp = gfc_create_var (mask_type, "mask");
4712 else mtmp = NULL_TREE;
4714 gfc_add_block_to_block (&body1, &lse.pre);
4715 gfc_add_block_to_block (&body1, &rse.pre);
4717 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4719 if (mask && (cmask || pmask))
4721 tmp = gfc_build_array_ref (mask, count, NULL);
4722 if (invert)
4723 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4724 gfc_add_modify (&body1, mtmp, tmp);
4727 if (cmask)
4729 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4730 tmp = cond;
4731 if (mask)
4732 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4733 mtmp, tmp);
4734 gfc_add_modify (&body1, tmp1, tmp);
4737 if (pmask)
4739 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4740 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4741 if (mask)
4742 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4743 tmp);
4744 gfc_add_modify (&body1, tmp1, tmp);
4747 gfc_add_block_to_block (&body1, &lse.post);
4748 gfc_add_block_to_block (&body1, &rse.post);
4750 if (lss == gfc_ss_terminator)
4752 gfc_add_block_to_block (&body, &body1);
4754 else
4756 /* Increment count. */
4757 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4758 count, gfc_index_one_node);
4759 gfc_add_modify (&body1, count, tmp1);
4761 /* Generate the copying loops. */
4762 gfc_trans_scalarizing_loops (&loop, &body1);
4764 gfc_add_block_to_block (&body, &loop.pre);
4765 gfc_add_block_to_block (&body, &loop.post);
4767 gfc_cleanup_loop (&loop);
4768 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4769 as tree nodes in SS may not be valid in different scope. */
4772 tmp1 = gfc_finish_block (&body);
4773 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4774 if (nested_forall_info != NULL)
4775 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4777 gfc_add_expr_to_block (block, tmp1);
4781 /* Translate an assignment statement in a WHERE statement or construct
4782 statement. The MASK expression is used to control which elements
4783 of EXPR1 shall be assigned. The sense of MASK is specified by
4784 INVERT. */
4786 static tree
4787 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4788 tree mask, bool invert,
4789 tree count1, tree count2,
4790 gfc_code *cnext)
4792 gfc_se lse;
4793 gfc_se rse;
4794 gfc_ss *lss;
4795 gfc_ss *lss_section;
4796 gfc_ss *rss;
4798 gfc_loopinfo loop;
4799 tree tmp;
4800 stmtblock_t block;
4801 stmtblock_t body;
4802 tree index, maskexpr;
4804 /* A defined assignment. */
4805 if (cnext && cnext->resolved_sym)
4806 return gfc_trans_call (cnext, true, mask, count1, invert);
4808 #if 0
4809 /* TODO: handle this special case.
4810 Special case a single function returning an array. */
4811 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4813 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4814 if (tmp)
4815 return tmp;
4817 #endif
4819 /* Assignment of the form lhs = rhs. */
4820 gfc_start_block (&block);
4822 gfc_init_se (&lse, NULL);
4823 gfc_init_se (&rse, NULL);
4825 /* Walk the lhs. */
4826 lss = gfc_walk_expr (expr1);
4827 rss = NULL;
4829 /* In each where-assign-stmt, the mask-expr and the variable being
4830 defined shall be arrays of the same shape. */
4831 gcc_assert (lss != gfc_ss_terminator);
4833 /* The assignment needs scalarization. */
4834 lss_section = lss;
4836 /* Find a non-scalar SS from the lhs. */
4837 while (lss_section != gfc_ss_terminator
4838 && lss_section->info->type != GFC_SS_SECTION)
4839 lss_section = lss_section->next;
4841 gcc_assert (lss_section != gfc_ss_terminator);
4843 /* Initialize the scalarizer. */
4844 gfc_init_loopinfo (&loop);
4846 /* Walk the rhs. */
4847 rss = gfc_walk_expr (expr2);
4848 if (rss == gfc_ss_terminator)
4850 /* The rhs is scalar. Add a ss for the expression. */
4851 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4852 rss->info->where = 1;
4855 /* Associate the SS with the loop. */
4856 gfc_add_ss_to_loop (&loop, lss);
4857 gfc_add_ss_to_loop (&loop, rss);
4859 /* Calculate the bounds of the scalarization. */
4860 gfc_conv_ss_startstride (&loop);
4862 /* Resolve any data dependencies in the statement. */
4863 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4865 /* Setup the scalarizing loops. */
4866 gfc_conv_loop_setup (&loop, &expr2->where);
4868 /* Setup the gfc_se structures. */
4869 gfc_copy_loopinfo_to_se (&lse, &loop);
4870 gfc_copy_loopinfo_to_se (&rse, &loop);
4872 rse.ss = rss;
4873 gfc_mark_ss_chain_used (rss, 1);
4874 if (loop.temp_ss == NULL)
4876 lse.ss = lss;
4877 gfc_mark_ss_chain_used (lss, 1);
4879 else
4881 lse.ss = loop.temp_ss;
4882 gfc_mark_ss_chain_used (lss, 3);
4883 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4886 /* Start the scalarized loop body. */
4887 gfc_start_scalarized_body (&loop, &body);
4889 /* Translate the expression. */
4890 gfc_conv_expr (&rse, expr2);
4891 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4892 gfc_conv_tmp_array_ref (&lse);
4893 else
4894 gfc_conv_expr (&lse, expr1);
4896 /* Form the mask expression according to the mask. */
4897 index = count1;
4898 maskexpr = gfc_build_array_ref (mask, index, NULL);
4899 if (invert)
4900 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4901 TREE_TYPE (maskexpr), maskexpr);
4903 /* Use the scalar assignment as is. */
4904 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4905 false, loop.temp_ss == NULL);
4907 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4909 gfc_add_expr_to_block (&body, tmp);
4911 if (lss == gfc_ss_terminator)
4913 /* Increment count1. */
4914 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4915 count1, gfc_index_one_node);
4916 gfc_add_modify (&body, count1, tmp);
4918 /* Use the scalar assignment as is. */
4919 gfc_add_block_to_block (&block, &body);
4921 else
4923 gcc_assert (lse.ss == gfc_ss_terminator
4924 && rse.ss == gfc_ss_terminator);
4926 if (loop.temp_ss != NULL)
4928 /* Increment count1 before finish the main body of a scalarized
4929 expression. */
4930 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4931 gfc_array_index_type, count1, gfc_index_one_node);
4932 gfc_add_modify (&body, count1, tmp);
4933 gfc_trans_scalarized_loop_boundary (&loop, &body);
4935 /* We need to copy the temporary to the actual lhs. */
4936 gfc_init_se (&lse, NULL);
4937 gfc_init_se (&rse, NULL);
4938 gfc_copy_loopinfo_to_se (&lse, &loop);
4939 gfc_copy_loopinfo_to_se (&rse, &loop);
4941 rse.ss = loop.temp_ss;
4942 lse.ss = lss;
4944 gfc_conv_tmp_array_ref (&rse);
4945 gfc_conv_expr (&lse, expr1);
4947 gcc_assert (lse.ss == gfc_ss_terminator
4948 && rse.ss == gfc_ss_terminator);
4950 /* Form the mask expression according to the mask tree list. */
4951 index = count2;
4952 maskexpr = gfc_build_array_ref (mask, index, NULL);
4953 if (invert)
4954 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4955 TREE_TYPE (maskexpr), maskexpr);
4957 /* Use the scalar assignment as is. */
4958 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, true);
4959 tmp = build3_v (COND_EXPR, maskexpr, tmp,
4960 build_empty_stmt (input_location));
4961 gfc_add_expr_to_block (&body, tmp);
4963 /* Increment count2. */
4964 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4965 gfc_array_index_type, count2,
4966 gfc_index_one_node);
4967 gfc_add_modify (&body, count2, tmp);
4969 else
4971 /* Increment count1. */
4972 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4973 gfc_array_index_type, count1,
4974 gfc_index_one_node);
4975 gfc_add_modify (&body, count1, tmp);
4978 /* Generate the copying loops. */
4979 gfc_trans_scalarizing_loops (&loop, &body);
4981 /* Wrap the whole thing up. */
4982 gfc_add_block_to_block (&block, &loop.pre);
4983 gfc_add_block_to_block (&block, &loop.post);
4984 gfc_cleanup_loop (&loop);
4987 return gfc_finish_block (&block);
4991 /* Translate the WHERE construct or statement.
4992 This function can be called iteratively to translate the nested WHERE
4993 construct or statement.
4994 MASK is the control mask. */
4996 static void
4997 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4998 forall_info * nested_forall_info, stmtblock_t * block)
5000 stmtblock_t inner_size_body;
5001 tree inner_size, size;
5002 gfc_ss *lss, *rss;
5003 tree mask_type;
5004 gfc_expr *expr1;
5005 gfc_expr *expr2;
5006 gfc_code *cblock;
5007 gfc_code *cnext;
5008 tree tmp;
5009 tree cond;
5010 tree count1, count2;
5011 bool need_cmask;
5012 bool need_pmask;
5013 int need_temp;
5014 tree pcmask = NULL_TREE;
5015 tree ppmask = NULL_TREE;
5016 tree cmask = NULL_TREE;
5017 tree pmask = NULL_TREE;
5018 gfc_actual_arglist *arg;
5020 /* the WHERE statement or the WHERE construct statement. */
5021 cblock = code->block;
5023 /* As the mask array can be very big, prefer compact boolean types. */
5024 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
5026 /* Determine which temporary masks are needed. */
5027 if (!cblock->block)
5029 /* One clause: No ELSEWHEREs. */
5030 need_cmask = (cblock->next != 0);
5031 need_pmask = false;
5033 else if (cblock->block->block)
5035 /* Three or more clauses: Conditional ELSEWHEREs. */
5036 need_cmask = true;
5037 need_pmask = true;
5039 else if (cblock->next)
5041 /* Two clauses, the first non-empty. */
5042 need_cmask = true;
5043 need_pmask = (mask != NULL_TREE
5044 && cblock->block->next != 0);
5046 else if (!cblock->block->next)
5048 /* Two clauses, both empty. */
5049 need_cmask = false;
5050 need_pmask = false;
5052 /* Two clauses, the first empty, the second non-empty. */
5053 else if (mask)
5055 need_cmask = (cblock->block->expr1 != 0);
5056 need_pmask = true;
5058 else
5060 need_cmask = true;
5061 need_pmask = false;
5064 if (need_cmask || need_pmask)
5066 /* Calculate the size of temporary needed by the mask-expr. */
5067 gfc_init_block (&inner_size_body);
5068 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
5069 &inner_size_body, &lss, &rss);
5071 gfc_free_ss_chain (lss);
5072 gfc_free_ss_chain (rss);
5074 /* Calculate the total size of temporary needed. */
5075 size = compute_overall_iter_number (nested_forall_info, inner_size,
5076 &inner_size_body, block);
5078 /* Check whether the size is negative. */
5079 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, size,
5080 gfc_index_zero_node);
5081 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
5082 cond, gfc_index_zero_node, size);
5083 size = gfc_evaluate_now (size, block);
5085 /* Allocate temporary for WHERE mask if needed. */
5086 if (need_cmask)
5087 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5088 &pcmask);
5090 /* Allocate temporary for !mask if needed. */
5091 if (need_pmask)
5092 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
5093 &ppmask);
5096 while (cblock)
5098 /* Each time around this loop, the where clause is conditional
5099 on the value of mask and invert, which are updated at the
5100 bottom of the loop. */
5102 /* Has mask-expr. */
5103 if (cblock->expr1)
5105 /* Ensure that the WHERE mask will be evaluated exactly once.
5106 If there are no statements in this WHERE/ELSEWHERE clause,
5107 then we don't need to update the control mask (cmask).
5108 If this is the last clause of the WHERE construct, then
5109 we don't need to update the pending control mask (pmask). */
5110 if (mask)
5111 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5112 mask, invert,
5113 cblock->next ? cmask : NULL_TREE,
5114 cblock->block ? pmask : NULL_TREE,
5115 mask_type, block);
5116 else
5117 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
5118 NULL_TREE, false,
5119 (cblock->next || cblock->block)
5120 ? cmask : NULL_TREE,
5121 NULL_TREE, mask_type, block);
5123 invert = false;
5125 /* It's a final elsewhere-stmt. No mask-expr is present. */
5126 else
5127 cmask = mask;
5129 /* The body of this where clause are controlled by cmask with
5130 sense specified by invert. */
5132 /* Get the assignment statement of a WHERE statement, or the first
5133 statement in where-body-construct of a WHERE construct. */
5134 cnext = cblock->next;
5135 while (cnext)
5137 switch (cnext->op)
5139 /* WHERE assignment statement. */
5140 case EXEC_ASSIGN_CALL:
5142 arg = cnext->ext.actual;
5143 expr1 = expr2 = NULL;
5144 for (; arg; arg = arg->next)
5146 if (!arg->expr)
5147 continue;
5148 if (expr1 == NULL)
5149 expr1 = arg->expr;
5150 else
5151 expr2 = arg->expr;
5153 goto evaluate;
5155 case EXEC_ASSIGN:
5156 expr1 = cnext->expr1;
5157 expr2 = cnext->expr2;
5158 evaluate:
5159 if (nested_forall_info != NULL)
5161 need_temp = gfc_check_dependency (expr1, expr2, 0);
5162 if ((need_temp || flag_test_forall_temp)
5163 && cnext->op != EXEC_ASSIGN_CALL)
5164 gfc_trans_assign_need_temp (expr1, expr2,
5165 cmask, invert,
5166 nested_forall_info, block);
5167 else
5169 /* Variables to control maskexpr. */
5170 count1 = gfc_create_var (gfc_array_index_type, "count1");
5171 count2 = gfc_create_var (gfc_array_index_type, "count2");
5172 gfc_add_modify (block, count1, gfc_index_zero_node);
5173 gfc_add_modify (block, count2, gfc_index_zero_node);
5175 tmp = gfc_trans_where_assign (expr1, expr2,
5176 cmask, invert,
5177 count1, count2,
5178 cnext);
5180 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
5181 tmp, 1);
5182 gfc_add_expr_to_block (block, tmp);
5185 else
5187 /* Variables to control maskexpr. */
5188 count1 = gfc_create_var (gfc_array_index_type, "count1");
5189 count2 = gfc_create_var (gfc_array_index_type, "count2");
5190 gfc_add_modify (block, count1, gfc_index_zero_node);
5191 gfc_add_modify (block, count2, gfc_index_zero_node);
5193 tmp = gfc_trans_where_assign (expr1, expr2,
5194 cmask, invert,
5195 count1, count2,
5196 cnext);
5197 gfc_add_expr_to_block (block, tmp);
5200 break;
5202 /* WHERE or WHERE construct is part of a where-body-construct. */
5203 case EXEC_WHERE:
5204 gfc_trans_where_2 (cnext, cmask, invert,
5205 nested_forall_info, block);
5206 break;
5208 default:
5209 gcc_unreachable ();
5212 /* The next statement within the same where-body-construct. */
5213 cnext = cnext->next;
5215 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
5216 cblock = cblock->block;
5217 if (mask == NULL_TREE)
5219 /* If we're the initial WHERE, we can simply invert the sense
5220 of the current mask to obtain the "mask" for the remaining
5221 ELSEWHEREs. */
5222 invert = true;
5223 mask = cmask;
5225 else
5227 /* Otherwise, for nested WHERE's we need to use the pending mask. */
5228 invert = false;
5229 mask = pmask;
5233 /* If we allocated a pending mask array, deallocate it now. */
5234 if (ppmask)
5236 tmp = gfc_call_free (ppmask);
5237 gfc_add_expr_to_block (block, tmp);
5240 /* If we allocated a current mask array, deallocate it now. */
5241 if (pcmask)
5243 tmp = gfc_call_free (pcmask);
5244 gfc_add_expr_to_block (block, tmp);
5248 /* Translate a simple WHERE construct or statement without dependencies.
5249 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
5250 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
5251 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
5253 static tree
5254 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
5256 stmtblock_t block, body;
5257 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
5258 tree tmp, cexpr, tstmt, estmt;
5259 gfc_ss *css, *tdss, *tsss;
5260 gfc_se cse, tdse, tsse, edse, esse;
5261 gfc_loopinfo loop;
5262 gfc_ss *edss = 0;
5263 gfc_ss *esss = 0;
5264 bool maybe_workshare = false;
5266 /* Allow the scalarizer to workshare simple where loops. */
5267 if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
5268 == OMPWS_WORKSHARE_FLAG)
5270 maybe_workshare = true;
5271 ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
5274 cond = cblock->expr1;
5275 tdst = cblock->next->expr1;
5276 tsrc = cblock->next->expr2;
5277 edst = eblock ? eblock->next->expr1 : NULL;
5278 esrc = eblock ? eblock->next->expr2 : NULL;
5280 gfc_start_block (&block);
5281 gfc_init_loopinfo (&loop);
5283 /* Handle the condition. */
5284 gfc_init_se (&cse, NULL);
5285 css = gfc_walk_expr (cond);
5286 gfc_add_ss_to_loop (&loop, css);
5288 /* Handle the then-clause. */
5289 gfc_init_se (&tdse, NULL);
5290 gfc_init_se (&tsse, NULL);
5291 tdss = gfc_walk_expr (tdst);
5292 tsss = gfc_walk_expr (tsrc);
5293 if (tsss == gfc_ss_terminator)
5295 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
5296 tsss->info->where = 1;
5298 gfc_add_ss_to_loop (&loop, tdss);
5299 gfc_add_ss_to_loop (&loop, tsss);
5301 if (eblock)
5303 /* Handle the else clause. */
5304 gfc_init_se (&edse, NULL);
5305 gfc_init_se (&esse, NULL);
5306 edss = gfc_walk_expr (edst);
5307 esss = gfc_walk_expr (esrc);
5308 if (esss == gfc_ss_terminator)
5310 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
5311 esss->info->where = 1;
5313 gfc_add_ss_to_loop (&loop, edss);
5314 gfc_add_ss_to_loop (&loop, esss);
5317 gfc_conv_ss_startstride (&loop);
5318 gfc_conv_loop_setup (&loop, &tdst->where);
5320 gfc_mark_ss_chain_used (css, 1);
5321 gfc_mark_ss_chain_used (tdss, 1);
5322 gfc_mark_ss_chain_used (tsss, 1);
5323 if (eblock)
5325 gfc_mark_ss_chain_used (edss, 1);
5326 gfc_mark_ss_chain_used (esss, 1);
5329 gfc_start_scalarized_body (&loop, &body);
5331 gfc_copy_loopinfo_to_se (&cse, &loop);
5332 gfc_copy_loopinfo_to_se (&tdse, &loop);
5333 gfc_copy_loopinfo_to_se (&tsse, &loop);
5334 cse.ss = css;
5335 tdse.ss = tdss;
5336 tsse.ss = tsss;
5337 if (eblock)
5339 gfc_copy_loopinfo_to_se (&edse, &loop);
5340 gfc_copy_loopinfo_to_se (&esse, &loop);
5341 edse.ss = edss;
5342 esse.ss = esss;
5345 gfc_conv_expr (&cse, cond);
5346 gfc_add_block_to_block (&body, &cse.pre);
5347 cexpr = cse.expr;
5349 gfc_conv_expr (&tsse, tsrc);
5350 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
5351 gfc_conv_tmp_array_ref (&tdse);
5352 else
5353 gfc_conv_expr (&tdse, tdst);
5355 if (eblock)
5357 gfc_conv_expr (&esse, esrc);
5358 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
5359 gfc_conv_tmp_array_ref (&edse);
5360 else
5361 gfc_conv_expr (&edse, edst);
5364 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, true);
5365 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts,
5366 false, true)
5367 : build_empty_stmt (input_location);
5368 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
5369 gfc_add_expr_to_block (&body, tmp);
5370 gfc_add_block_to_block (&body, &cse.post);
5372 if (maybe_workshare)
5373 ompws_flags &= ~OMPWS_SCALARIZER_BODY;
5374 gfc_trans_scalarizing_loops (&loop, &body);
5375 gfc_add_block_to_block (&block, &loop.pre);
5376 gfc_add_block_to_block (&block, &loop.post);
5377 gfc_cleanup_loop (&loop);
5379 return gfc_finish_block (&block);
5382 /* As the WHERE or WHERE construct statement can be nested, we call
5383 gfc_trans_where_2 to do the translation, and pass the initial
5384 NULL values for both the control mask and the pending control mask. */
5386 tree
5387 gfc_trans_where (gfc_code * code)
5389 stmtblock_t block;
5390 gfc_code *cblock;
5391 gfc_code *eblock;
5393 cblock = code->block;
5394 if (cblock->next
5395 && cblock->next->op == EXEC_ASSIGN
5396 && !cblock->next->next)
5398 eblock = cblock->block;
5399 if (!eblock)
5401 /* A simple "WHERE (cond) x = y" statement or block is
5402 dependence free if cond is not dependent upon writing x,
5403 and the source y is unaffected by the destination x. */
5404 if (!gfc_check_dependency (cblock->next->expr1,
5405 cblock->expr1, 0)
5406 && !gfc_check_dependency (cblock->next->expr1,
5407 cblock->next->expr2, 0))
5408 return gfc_trans_where_3 (cblock, NULL);
5410 else if (!eblock->expr1
5411 && !eblock->block
5412 && eblock->next
5413 && eblock->next->op == EXEC_ASSIGN
5414 && !eblock->next->next)
5416 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5417 block is dependence free if cond is not dependent on writes
5418 to x1 and x2, y1 is not dependent on writes to x2, and y2
5419 is not dependent on writes to x1, and both y's are not
5420 dependent upon their own x's. In addition to this, the
5421 final two dependency checks below exclude all but the same
5422 array reference if the where and elswhere destinations
5423 are the same. In short, this is VERY conservative and this
5424 is needed because the two loops, required by the standard
5425 are coalesced in gfc_trans_where_3. */
5426 if (!gfc_check_dependency (cblock->next->expr1,
5427 cblock->expr1, 0)
5428 && !gfc_check_dependency (eblock->next->expr1,
5429 cblock->expr1, 0)
5430 && !gfc_check_dependency (cblock->next->expr1,
5431 eblock->next->expr2, 1)
5432 && !gfc_check_dependency (eblock->next->expr1,
5433 cblock->next->expr2, 1)
5434 && !gfc_check_dependency (cblock->next->expr1,
5435 cblock->next->expr2, 1)
5436 && !gfc_check_dependency (eblock->next->expr1,
5437 eblock->next->expr2, 1)
5438 && !gfc_check_dependency (cblock->next->expr1,
5439 eblock->next->expr1, 0)
5440 && !gfc_check_dependency (eblock->next->expr1,
5441 cblock->next->expr1, 0))
5442 return gfc_trans_where_3 (cblock, eblock);
5446 gfc_start_block (&block);
5448 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5450 return gfc_finish_block (&block);
5454 /* CYCLE a DO loop. The label decl has already been created by
5455 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5456 node at the head of the loop. We must mark the label as used. */
5458 tree
5459 gfc_trans_cycle (gfc_code * code)
5461 tree cycle_label;
5463 cycle_label = code->ext.which_construct->cycle_label;
5464 gcc_assert (cycle_label);
5466 TREE_USED (cycle_label) = 1;
5467 return build1_v (GOTO_EXPR, cycle_label);
5471 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5472 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5473 loop. */
5475 tree
5476 gfc_trans_exit (gfc_code * code)
5478 tree exit_label;
5480 exit_label = code->ext.which_construct->exit_label;
5481 gcc_assert (exit_label);
5483 TREE_USED (exit_label) = 1;
5484 return build1_v (GOTO_EXPR, exit_label);
5488 /* Get the initializer expression for the code and expr of an allocate.
5489 When no initializer is needed return NULL. */
5491 static gfc_expr *
5492 allocate_get_initializer (gfc_code * code, gfc_expr * expr)
5494 if (!gfc_bt_struct (expr->ts.type) && expr->ts.type != BT_CLASS)
5495 return NULL;
5497 /* An explicit type was given in allocate ( T:: object). */
5498 if (code->ext.alloc.ts.type == BT_DERIVED
5499 && (code->ext.alloc.ts.u.derived->attr.alloc_comp
5500 || gfc_has_default_initializer (code->ext.alloc.ts.u.derived)))
5501 return gfc_default_initializer (&code->ext.alloc.ts);
5503 if (gfc_bt_struct (expr->ts.type)
5504 && (expr->ts.u.derived->attr.alloc_comp
5505 || gfc_has_default_initializer (expr->ts.u.derived)))
5506 return gfc_default_initializer (&expr->ts);
5508 if (expr->ts.type == BT_CLASS
5509 && (CLASS_DATA (expr)->ts.u.derived->attr.alloc_comp
5510 || gfc_has_default_initializer (CLASS_DATA (expr)->ts.u.derived)))
5511 return gfc_default_initializer (&CLASS_DATA (expr)->ts);
5513 return NULL;
5516 /* Translate the ALLOCATE statement. */
5518 tree
5519 gfc_trans_allocate (gfc_code * code)
5521 gfc_alloc *al;
5522 gfc_expr *expr, *e3rhs = NULL, *init_expr;
5523 gfc_se se, se_sz;
5524 tree tmp;
5525 tree parm;
5526 tree stat;
5527 tree errmsg;
5528 tree errlen;
5529 tree label_errmsg;
5530 tree label_finish;
5531 tree memsz;
5532 tree al_vptr, al_len;
5533 /* If an expr3 is present, then store the tree for accessing its
5534 _vptr, and _len components in the variables, respectively. The
5535 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5536 the trees may be the NULL_TREE indicating that this is not
5537 available for expr3's type. */
5538 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5539 /* Classify what expr3 stores. */
5540 enum { E3_UNSET = 0, E3_SOURCE, E3_MOLD, E3_DESC } e3_is;
5541 stmtblock_t block;
5542 stmtblock_t post;
5543 tree nelems;
5544 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set, is_coarray;
5545 bool needs_caf_sync, caf_refs_comp;
5546 gfc_symtree *newsym = NULL;
5547 symbol_attribute caf_attr;
5549 if (!code->ext.alloc.list)
5550 return NULL_TREE;
5552 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5553 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5554 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5555 e3_is = E3_UNSET;
5556 is_coarray = needs_caf_sync = false;
5558 gfc_init_block (&block);
5559 gfc_init_block (&post);
5561 /* STAT= (and maybe ERRMSG=) is present. */
5562 if (code->expr1)
5564 /* STAT=. */
5565 tree gfc_int4_type_node = gfc_get_int_type (4);
5566 stat = gfc_create_var (gfc_int4_type_node, "stat");
5568 /* ERRMSG= only makes sense with STAT=. */
5569 if (code->expr2)
5571 gfc_init_se (&se, NULL);
5572 se.want_pointer = 1;
5573 gfc_conv_expr_lhs (&se, code->expr2);
5574 errmsg = se.expr;
5575 errlen = se.string_length;
5577 else
5579 errmsg = null_pointer_node;
5580 errlen = build_int_cst (gfc_charlen_type_node, 0);
5583 /* GOTO destinations. */
5584 label_errmsg = gfc_build_label_decl (NULL_TREE);
5585 label_finish = gfc_build_label_decl (NULL_TREE);
5586 TREE_USED (label_finish) = 0;
5589 /* When an expr3 is present evaluate it only once. The standards prevent a
5590 dependency of expr3 on the objects in the allocate list. An expr3 can
5591 be pre-evaluated in all cases. One just has to make sure, to use the
5592 correct way, i.e., to get the descriptor or to get a reference
5593 expression. */
5594 if (code->expr3)
5596 bool vtab_needed = false, temp_var_needed = false,
5597 temp_obj_created = false;
5599 is_coarray = gfc_is_coarray (code->expr3);
5601 /* Figure whether we need the vtab from expr3. */
5602 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5603 al = al->next)
5604 vtab_needed = (al->expr->ts.type == BT_CLASS);
5606 gfc_init_se (&se, NULL);
5607 /* When expr3 is a variable, i.e., a very simple expression,
5608 then convert it once here. */
5609 if (code->expr3->expr_type == EXPR_VARIABLE
5610 || code->expr3->expr_type == EXPR_ARRAY
5611 || code->expr3->expr_type == EXPR_CONSTANT)
5613 if (!code->expr3->mold
5614 || code->expr3->ts.type == BT_CHARACTER
5615 || vtab_needed
5616 || code->ext.alloc.arr_spec_from_expr3)
5618 /* Convert expr3 to a tree. For all "simple" expression just
5619 get the descriptor or the reference, respectively, depending
5620 on the rank of the expr. */
5621 if (code->ext.alloc.arr_spec_from_expr3 || code->expr3->rank != 0)
5622 gfc_conv_expr_descriptor (&se, code->expr3);
5623 else
5625 gfc_conv_expr_reference (&se, code->expr3);
5627 /* gfc_conv_expr_reference wraps POINTER_PLUS_EXPR in a
5628 NOP_EXPR, which prevents gfortran from getting the vptr
5629 from the source=-expression. Remove the NOP_EXPR and go
5630 with the POINTER_PLUS_EXPR in this case. */
5631 if (code->expr3->ts.type == BT_CLASS
5632 && TREE_CODE (se.expr) == NOP_EXPR
5633 && (TREE_CODE (TREE_OPERAND (se.expr, 0))
5634 == POINTER_PLUS_EXPR
5635 || is_coarray))
5636 se.expr = TREE_OPERAND (se.expr, 0);
5638 /* Create a temp variable only for component refs to prevent
5639 having to go through the full deref-chain each time and to
5640 simplfy computation of array properties. */
5641 temp_var_needed = TREE_CODE (se.expr) == COMPONENT_REF;
5644 else
5646 /* In all other cases evaluate the expr3. */
5647 symbol_attribute attr;
5648 /* Get the descriptor for all arrays, that are not allocatable or
5649 pointer, because the latter are descriptors already.
5650 The exception are function calls returning a class object:
5651 The descriptor is stored in their results _data component, which
5652 is easier to access, when first a temporary variable for the
5653 result is created and the descriptor retrieved from there. */
5654 attr = gfc_expr_attr (code->expr3);
5655 if (code->expr3->rank != 0
5656 && ((!attr.allocatable && !attr.pointer)
5657 || (code->expr3->expr_type == EXPR_FUNCTION
5658 && (code->expr3->ts.type != BT_CLASS
5659 || (code->expr3->value.function.isym
5660 && code->expr3->value.function.isym
5661 ->transformational)))))
5662 gfc_conv_expr_descriptor (&se, code->expr3);
5663 else
5664 gfc_conv_expr_reference (&se, code->expr3);
5665 if (code->expr3->ts.type == BT_CLASS)
5666 gfc_conv_class_to_class (&se, code->expr3,
5667 code->expr3->ts,
5668 false, true,
5669 false, false);
5670 temp_obj_created = temp_var_needed = !VAR_P (se.expr);
5672 gfc_add_block_to_block (&block, &se.pre);
5673 gfc_add_block_to_block (&post, &se.post);
5675 /* Special case when string in expr3 is zero. */
5676 if (code->expr3->ts.type == BT_CHARACTER
5677 && integer_zerop (se.string_length))
5679 gfc_init_se (&se, NULL);
5680 temp_var_needed = false;
5681 expr3_len = integer_zero_node;
5682 e3_is = E3_MOLD;
5684 /* Prevent aliasing, i.e., se.expr may be already a
5685 variable declaration. */
5686 else if (se.expr != NULL_TREE && temp_var_needed)
5688 tree var, desc;
5689 tmp = GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)) || is_coarray ?
5690 se.expr
5691 : build_fold_indirect_ref_loc (input_location, se.expr);
5693 /* Get the array descriptor and prepare it to be assigned to the
5694 temporary variable var. For classes the array descriptor is
5695 in the _data component and the object goes into the
5696 GFC_DECL_SAVED_DESCRIPTOR. */
5697 if (code->expr3->ts.type == BT_CLASS
5698 && code->expr3->rank != 0)
5700 /* When an array_ref was in expr3, then the descriptor is the
5701 first operand. */
5702 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5704 desc = TREE_OPERAND (tmp, 0);
5706 else
5708 desc = tmp;
5709 tmp = gfc_class_data_get (tmp);
5711 if (code->ext.alloc.arr_spec_from_expr3)
5712 e3_is = E3_DESC;
5714 else
5715 desc = !is_coarray ? se.expr
5716 : TREE_OPERAND (TREE_OPERAND (se.expr, 0), 0);
5717 /* We need a regular (non-UID) symbol here, therefore give a
5718 prefix. */
5719 var = gfc_create_var (TREE_TYPE (tmp), "source");
5720 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp)) || is_coarray)
5722 gfc_allocate_lang_decl (var);
5723 GFC_DECL_SAVED_DESCRIPTOR (var) = desc;
5725 gfc_add_modify_loc (input_location, &block, var, tmp);
5727 expr3 = var;
5728 if (se.string_length)
5729 /* Evaluate it assuming that it also is complicated like expr3. */
5730 expr3_len = gfc_evaluate_now (se.string_length, &block);
5732 else
5734 expr3 = se.expr;
5735 expr3_len = se.string_length;
5738 /* Deallocate any allocatable components in expressions that use a
5739 temporary object, i.e. are not a simple alias of to an EXPR_VARIABLE.
5740 E.g. temporaries of a function call need freeing of their components
5741 here. */
5742 if ((code->expr3->ts.type == BT_DERIVED
5743 || code->expr3->ts.type == BT_CLASS)
5744 && (code->expr3->expr_type != EXPR_VARIABLE || temp_obj_created)
5745 && code->expr3->ts.u.derived->attr.alloc_comp)
5747 tmp = gfc_deallocate_alloc_comp (code->expr3->ts.u.derived,
5748 expr3, code->expr3->rank);
5749 gfc_prepend_expr_to_block (&post, tmp);
5752 /* Store what the expr3 is to be used for. */
5753 if (e3_is == E3_UNSET)
5754 e3_is = expr3 != NULL_TREE ?
5755 (code->ext.alloc.arr_spec_from_expr3 ?
5756 E3_DESC
5757 : (code->expr3->mold ? E3_MOLD : E3_SOURCE))
5758 : E3_UNSET;
5760 /* Figure how to get the _vtab entry. This also obtains the tree
5761 expression for accessing the _len component, because only
5762 unlimited polymorphic objects, which are a subcategory of class
5763 types, have a _len component. */
5764 if (code->expr3->ts.type == BT_CLASS)
5766 gfc_expr *rhs;
5767 tmp = expr3 != NULL_TREE && POINTER_TYPE_P (TREE_TYPE (expr3)) ?
5768 build_fold_indirect_ref (expr3): expr3;
5769 /* Polymorphic SOURCE: VPTR must be determined at run time.
5770 expr3 may be a temporary array declaration, therefore check for
5771 GFC_CLASS_TYPE_P before trying to get the _vptr component. */
5772 if (tmp != NULL_TREE
5773 && (e3_is == E3_DESC
5774 || (GFC_CLASS_TYPE_P (TREE_TYPE (tmp))
5775 && (VAR_P (tmp) || !code->expr3->ref))
5776 || (VAR_P (tmp) && DECL_LANG_SPECIFIC (tmp))))
5777 tmp = gfc_class_vptr_get (expr3);
5778 else
5780 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5781 gfc_add_vptr_component (rhs);
5782 gfc_init_se (&se, NULL);
5783 se.want_pointer = 1;
5784 gfc_conv_expr (&se, rhs);
5785 tmp = se.expr;
5786 gfc_free_expr (rhs);
5788 /* Set the element size. */
5789 expr3_esize = gfc_vptr_size_get (tmp);
5790 if (vtab_needed)
5791 expr3_vptr = tmp;
5792 /* Initialize the ref to the _len component. */
5793 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5795 /* Same like for retrieving the _vptr. */
5796 if (expr3 != NULL_TREE && !code->expr3->ref)
5797 expr3_len = gfc_class_len_get (expr3);
5798 else
5800 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5801 gfc_add_len_component (rhs);
5802 gfc_init_se (&se, NULL);
5803 gfc_conv_expr (&se, rhs);
5804 expr3_len = se.expr;
5805 gfc_free_expr (rhs);
5809 else
5811 /* When the object to allocate is polymorphic type, then it
5812 needs its vtab set correctly, so deduce the required _vtab
5813 and _len from the source expression. */
5814 if (vtab_needed)
5816 /* VPTR is fixed at compile time. */
5817 gfc_symbol *vtab;
5819 vtab = gfc_find_vtab (&code->expr3->ts);
5820 gcc_assert (vtab);
5821 expr3_vptr = gfc_get_symbol_decl (vtab);
5822 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5823 expr3_vptr);
5825 /* _len component needs to be set, when ts is a character
5826 array. */
5827 if (expr3_len == NULL_TREE
5828 && code->expr3->ts.type == BT_CHARACTER)
5830 if (code->expr3->ts.u.cl
5831 && code->expr3->ts.u.cl->length)
5833 gfc_init_se (&se, NULL);
5834 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5835 gfc_add_block_to_block (&block, &se.pre);
5836 expr3_len = gfc_evaluate_now (se.expr, &block);
5838 gcc_assert (expr3_len);
5840 /* For character arrays only the kind's size is needed, because
5841 the array mem_size is _len * (elem_size = kind_size).
5842 For all other get the element size in the normal way. */
5843 if (code->expr3->ts.type == BT_CHARACTER)
5844 expr3_esize = TYPE_SIZE_UNIT (
5845 gfc_get_char_type (code->expr3->ts.kind));
5846 else
5847 expr3_esize = TYPE_SIZE_UNIT (
5848 gfc_typenode_for_spec (&code->expr3->ts));
5850 gcc_assert (expr3_esize);
5851 expr3_esize = fold_convert (sizetype, expr3_esize);
5852 if (e3_is == E3_MOLD)
5853 /* The expr3 is no longer valid after this point. */
5854 expr3 = NULL_TREE;
5856 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5858 /* Compute the explicit typespec given only once for all objects
5859 to allocate. */
5860 if (code->ext.alloc.ts.type != BT_CHARACTER)
5861 expr3_esize = TYPE_SIZE_UNIT (
5862 gfc_typenode_for_spec (&code->ext.alloc.ts));
5863 else
5865 gfc_expr *sz;
5866 gcc_assert (code->ext.alloc.ts.u.cl->length != NULL);
5867 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5868 gfc_init_se (&se_sz, NULL);
5869 gfc_conv_expr (&se_sz, sz);
5870 gfc_free_expr (sz);
5871 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5872 tmp = TYPE_SIZE_UNIT (tmp);
5873 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5874 gfc_add_block_to_block (&block, &se_sz.pre);
5875 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5876 TREE_TYPE (se_sz.expr),
5877 tmp, se_sz.expr);
5878 expr3_esize = gfc_evaluate_now (expr3_esize, &block);
5882 /* The routine gfc_trans_assignment () already implements all
5883 techniques needed. Unfortunately we may have a temporary
5884 variable for the source= expression here. When that is the
5885 case convert this variable into a temporary gfc_expr of type
5886 EXPR_VARIABLE and used it as rhs for the assignment. The
5887 advantage is, that we get scalarizer support for free,
5888 don't have to take care about scalar to array treatment and
5889 will benefit of every enhancements gfc_trans_assignment ()
5890 gets.
5891 No need to check whether e3_is is E3_UNSET, because that is
5892 done by expr3 != NULL_TREE.
5893 Exclude variables since the following block does not handle
5894 array sections. In any case, there is no harm in sending
5895 variables to gfc_trans_assignment because there is no
5896 evaluation of variables. */
5897 if (code->expr3)
5899 if (code->expr3->expr_type != EXPR_VARIABLE
5900 && e3_is != E3_MOLD && expr3 != NULL_TREE
5901 && DECL_P (expr3) && DECL_ARTIFICIAL (expr3))
5903 /* Build a temporary symtree and symbol. Do not add it to the current
5904 namespace to prevent accidently modifying a colliding
5905 symbol's as. */
5906 newsym = XCNEW (gfc_symtree);
5907 /* The name of the symtree should be unique, because gfc_create_var ()
5908 took care about generating the identifier. */
5909 newsym->name
5910 = gfc_get_string ("%s", IDENTIFIER_POINTER (DECL_NAME (expr3)));
5911 newsym->n.sym = gfc_new_symbol (newsym->name, NULL);
5912 /* The backend_decl is known. It is expr3, which is inserted
5913 here. */
5914 newsym->n.sym->backend_decl = expr3;
5915 e3rhs = gfc_get_expr ();
5916 e3rhs->rank = code->expr3->rank;
5917 e3rhs->symtree = newsym;
5918 /* Mark the symbol referenced or gfc_trans_assignment will bug. */
5919 newsym->n.sym->attr.referenced = 1;
5920 e3rhs->expr_type = EXPR_VARIABLE;
5921 e3rhs->where = code->expr3->where;
5922 /* Set the symbols type, upto it was BT_UNKNOWN. */
5923 if (IS_CLASS_ARRAY (code->expr3)
5924 && code->expr3->expr_type == EXPR_FUNCTION
5925 && code->expr3->value.function.isym
5926 && code->expr3->value.function.isym->transformational)
5928 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
5930 else if (code->expr3->ts.type == BT_CLASS
5931 && !GFC_CLASS_TYPE_P (TREE_TYPE (expr3)))
5932 e3rhs->ts = CLASS_DATA (code->expr3)->ts;
5933 else
5934 e3rhs->ts = code->expr3->ts;
5935 newsym->n.sym->ts = e3rhs->ts;
5936 /* Check whether the expr3 is array valued. */
5937 if (e3rhs->rank)
5939 gfc_array_spec *arr;
5940 arr = gfc_get_array_spec ();
5941 arr->rank = e3rhs->rank;
5942 arr->type = AS_DEFERRED;
5943 /* Set the dimension and pointer attribute for arrays
5944 to be on the safe side. */
5945 newsym->n.sym->attr.dimension = 1;
5946 newsym->n.sym->attr.pointer = 1;
5947 newsym->n.sym->as = arr;
5948 if (IS_CLASS_ARRAY (code->expr3)
5949 && code->expr3->expr_type == EXPR_FUNCTION
5950 && code->expr3->value.function.isym
5951 && code->expr3->value.function.isym->transformational)
5953 gfc_array_spec *tarr;
5954 tarr = gfc_get_array_spec ();
5955 *tarr = *arr;
5956 e3rhs->ts.u.derived->as = tarr;
5958 gfc_add_full_array_ref (e3rhs, arr);
5960 else if (POINTER_TYPE_P (TREE_TYPE (expr3)))
5961 newsym->n.sym->attr.pointer = 1;
5962 /* The string length is known, too. Set it for char arrays. */
5963 if (e3rhs->ts.type == BT_CHARACTER)
5964 newsym->n.sym->ts.u.cl->backend_decl = expr3_len;
5965 gfc_commit_symbol (newsym->n.sym);
5967 else
5968 e3rhs = gfc_copy_expr (code->expr3);
5971 /* Loop over all objects to allocate. */
5972 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5974 expr = gfc_copy_expr (al->expr);
5975 /* UNLIMITED_POLY () needs the _data component to be set, when
5976 expr is a unlimited polymorphic object. But the _data component
5977 has not been set yet, so check the derived type's attr for the
5978 unlimited polymorphic flag to be safe. */
5979 upoly_expr = UNLIMITED_POLY (expr)
5980 || (expr->ts.type == BT_DERIVED
5981 && expr->ts.u.derived->attr.unlimited_polymorphic);
5982 gfc_init_se (&se, NULL);
5984 /* For class types prepare the expressions to ref the _vptr
5985 and the _len component. The latter for unlimited polymorphic
5986 types only. */
5987 if (expr->ts.type == BT_CLASS)
5989 gfc_expr *expr_ref_vptr, *expr_ref_len;
5990 gfc_add_data_component (expr);
5991 /* Prep the vptr handle. */
5992 expr_ref_vptr = gfc_copy_expr (al->expr);
5993 gfc_add_vptr_component (expr_ref_vptr);
5994 se.want_pointer = 1;
5995 gfc_conv_expr (&se, expr_ref_vptr);
5996 al_vptr = se.expr;
5997 se.want_pointer = 0;
5998 gfc_free_expr (expr_ref_vptr);
5999 /* Allocated unlimited polymorphic objects always have a _len
6000 component. */
6001 if (upoly_expr)
6003 expr_ref_len = gfc_copy_expr (al->expr);
6004 gfc_add_len_component (expr_ref_len);
6005 gfc_conv_expr (&se, expr_ref_len);
6006 al_len = se.expr;
6007 gfc_free_expr (expr_ref_len);
6009 else
6010 /* In a loop ensure that all loop variable dependent variables
6011 are initialized at the same spot in all execution paths. */
6012 al_len = NULL_TREE;
6014 else
6015 al_vptr = al_len = NULL_TREE;
6017 se.want_pointer = 1;
6018 se.descriptor_only = 1;
6020 gfc_conv_expr (&se, expr);
6021 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6022 /* se.string_length now stores the .string_length variable of expr
6023 needed to allocate character(len=:) arrays. */
6024 al_len = se.string_length;
6026 al_len_needs_set = al_len != NULL_TREE;
6027 /* When allocating an array one can not use much of the
6028 pre-evaluated expr3 expressions, because for most of them the
6029 scalarizer is needed which is not available in the pre-evaluation
6030 step. Therefore gfc_array_allocate () is responsible (and able)
6031 to handle the complete array allocation. Only the element size
6032 needs to be provided, which is done most of the time by the
6033 pre-evaluation step. */
6034 nelems = NULL_TREE;
6035 if (expr3_len && (code->expr3->ts.type == BT_CHARACTER
6036 || code->expr3->ts.type == BT_CLASS))
6038 /* When al is an array, then the element size for each element
6039 in the array is needed, which is the product of the len and
6040 esize for char arrays. For unlimited polymorphics len can be
6041 zero, therefore take the maximum of len and one. */
6042 tmp = fold_build2_loc (input_location, MAX_EXPR,
6043 TREE_TYPE (expr3_len),
6044 expr3_len, fold_convert (TREE_TYPE (expr3_len),
6045 integer_one_node));
6046 tmp = fold_build2_loc (input_location, MULT_EXPR,
6047 TREE_TYPE (expr3_esize), expr3_esize,
6048 fold_convert (TREE_TYPE (expr3_esize), tmp));
6050 else
6051 tmp = expr3_esize;
6052 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
6053 label_finish, tmp, &nelems,
6054 e3rhs ? e3rhs : code->expr3,
6055 e3_is == E3_DESC ? expr3 : NULL_TREE,
6056 code->expr3 != NULL && e3_is == E3_DESC
6057 && code->expr3->expr_type == EXPR_ARRAY))
6059 /* A scalar or derived type. First compute the size to
6060 allocate.
6062 expr3_len is set when expr3 is an unlimited polymorphic
6063 object or a deferred length string. */
6064 if (expr3_len != NULL_TREE)
6066 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
6067 tmp = fold_build2_loc (input_location, MULT_EXPR,
6068 TREE_TYPE (expr3_esize),
6069 expr3_esize, tmp);
6070 if (code->expr3->ts.type != BT_CLASS)
6071 /* expr3 is a deferred length string, i.e., we are
6072 done. */
6073 memsz = tmp;
6074 else
6076 /* For unlimited polymorphic enties build
6077 (len > 0) ? element_size * len : element_size
6078 to compute the number of bytes to allocate.
6079 This allows the allocation of unlimited polymorphic
6080 objects from an expr3 that is also unlimited
6081 polymorphic and stores a _len dependent object,
6082 e.g., a string. */
6083 memsz = fold_build2_loc (input_location, GT_EXPR,
6084 boolean_type_node, expr3_len,
6085 integer_zero_node);
6086 memsz = fold_build3_loc (input_location, COND_EXPR,
6087 TREE_TYPE (expr3_esize),
6088 memsz, tmp, expr3_esize);
6091 else if (expr3_esize != NULL_TREE)
6092 /* Any other object in expr3 just needs element size in
6093 bytes. */
6094 memsz = expr3_esize;
6095 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
6096 || (upoly_expr
6097 && code->ext.alloc.ts.type == BT_CHARACTER))
6099 /* Allocating deferred length char arrays need the length
6100 to allocate in the alloc_type_spec. But also unlimited
6101 polymorphic objects may be allocated as char arrays.
6102 Both are handled here. */
6103 gfc_init_se (&se_sz, NULL);
6104 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6105 gfc_add_block_to_block (&se.pre, &se_sz.pre);
6106 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
6107 gfc_add_block_to_block (&se.pre, &se_sz.post);
6108 expr3_len = se_sz.expr;
6109 tmp_expr3_len_flag = true;
6110 tmp = TYPE_SIZE_UNIT (
6111 gfc_get_char_type (code->ext.alloc.ts.kind));
6112 memsz = fold_build2_loc (input_location, MULT_EXPR,
6113 TREE_TYPE (tmp),
6114 fold_convert (TREE_TYPE (tmp),
6115 expr3_len),
6116 tmp);
6118 else if (expr->ts.type == BT_CHARACTER)
6120 /* Compute the number of bytes needed to allocate a fixed
6121 length char array. */
6122 gcc_assert (se.string_length != NULL_TREE);
6123 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
6124 memsz = fold_build2_loc (input_location, MULT_EXPR,
6125 TREE_TYPE (tmp), tmp,
6126 fold_convert (TREE_TYPE (tmp),
6127 se.string_length));
6129 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
6130 /* Handle all types, where the alloc_type_spec is set. */
6131 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
6132 else
6133 /* Handle size computation of the type declared to alloc. */
6134 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
6136 /* Store the caf-attributes for latter use. */
6137 if (flag_coarray == GFC_FCOARRAY_LIB
6138 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6139 .codimension)
6141 /* Scalar allocatable components in coarray'ed derived types make
6142 it here and are treated now. */
6143 tree caf_decl, token;
6144 gfc_se caf_se;
6146 is_coarray = true;
6147 /* Set flag, to add synchronize after the allocate. */
6148 needs_caf_sync = needs_caf_sync
6149 || caf_attr.coarray_comp || !caf_refs_comp;
6151 gfc_init_se (&caf_se, NULL);
6153 caf_decl = gfc_get_tree_for_caf_expr (expr);
6154 gfc_get_caf_token_offset (&caf_se, &token, NULL, caf_decl,
6155 NULL_TREE, NULL);
6156 gfc_add_block_to_block (&se.pre, &caf_se.pre);
6157 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6158 gfc_build_addr_expr (NULL_TREE, token),
6159 NULL_TREE, NULL_TREE, NULL_TREE,
6160 label_finish, expr, 1);
6162 /* Allocate - for non-pointers with re-alloc checking. */
6163 else if (gfc_expr_attr (expr).allocatable)
6164 gfc_allocate_allocatable (&se.pre, se.expr, memsz,
6165 NULL_TREE, stat, errmsg, errlen,
6166 label_finish, expr, 0);
6167 else
6168 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
6170 else
6172 /* Allocating coarrays needs a sync after the allocate executed.
6173 Set the flag to add the sync after all objects are allocated. */
6174 if (flag_coarray == GFC_FCOARRAY_LIB
6175 && (caf_attr = gfc_caf_attr (expr, true, &caf_refs_comp))
6176 .codimension)
6178 is_coarray = true;
6179 needs_caf_sync = needs_caf_sync
6180 || caf_attr.coarray_comp || !caf_refs_comp;
6183 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6184 && expr3_len != NULL_TREE)
6186 /* Arrays need to have a _len set before the array
6187 descriptor is filled. */
6188 gfc_add_modify (&block, al_len,
6189 fold_convert (TREE_TYPE (al_len), expr3_len));
6190 /* Prevent setting the length twice. */
6191 al_len_needs_set = false;
6193 else if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
6194 && code->ext.alloc.ts.u.cl->length)
6196 /* Cover the cases where a string length is explicitly
6197 specified by a type spec for deferred length character
6198 arrays or unlimited polymorphic objects without a
6199 source= or mold= expression. */
6200 gfc_init_se (&se_sz, NULL);
6201 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6202 gfc_add_block_to_block (&block, &se_sz.pre);
6203 gfc_add_modify (&block, al_len,
6204 fold_convert (TREE_TYPE (al_len),
6205 se_sz.expr));
6206 al_len_needs_set = false;
6210 gfc_add_block_to_block (&block, &se.pre);
6212 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
6213 if (code->expr1)
6215 tmp = build1_v (GOTO_EXPR, label_errmsg);
6216 parm = fold_build2_loc (input_location, NE_EXPR,
6217 boolean_type_node, stat,
6218 build_int_cst (TREE_TYPE (stat), 0));
6219 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6220 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
6221 tmp, build_empty_stmt (input_location));
6222 gfc_add_expr_to_block (&block, tmp);
6225 /* Set the vptr only when no source= is set. When source= is set, then
6226 the trans_assignment below will set the vptr. */
6227 if (al_vptr != NULL_TREE && (!code->expr3 || code->expr3->mold))
6229 if (expr3_vptr != NULL_TREE)
6230 /* The vtab is already known, so just assign it. */
6231 gfc_add_modify (&block, al_vptr,
6232 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
6233 else
6235 /* VPTR is fixed at compile time. */
6236 gfc_symbol *vtab;
6237 gfc_typespec *ts;
6239 if (code->expr3)
6240 /* Although expr3 is pre-evaluated above, it may happen,
6241 that for arrays or in mold= cases the pre-evaluation
6242 was not successful. In these rare cases take the vtab
6243 from the typespec of expr3 here. */
6244 ts = &code->expr3->ts;
6245 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
6246 /* The alloc_type_spec gives the type to allocate or the
6247 al is unlimited polymorphic, which enforces the use of
6248 an alloc_type_spec that is not necessarily a BT_DERIVED. */
6249 ts = &code->ext.alloc.ts;
6250 else
6251 /* Prepare for setting the vtab as declared. */
6252 ts = &expr->ts;
6254 vtab = gfc_find_vtab (ts);
6255 gcc_assert (vtab);
6256 tmp = gfc_build_addr_expr (NULL_TREE,
6257 gfc_get_symbol_decl (vtab));
6258 gfc_add_modify (&block, al_vptr,
6259 fold_convert (TREE_TYPE (al_vptr), tmp));
6263 /* Add assignment for string length. */
6264 if (al_len != NULL_TREE && al_len_needs_set)
6266 if (expr3_len != NULL_TREE)
6268 gfc_add_modify (&block, al_len,
6269 fold_convert (TREE_TYPE (al_len),
6270 expr3_len));
6271 /* When tmp_expr3_len_flag is set, then expr3_len is
6272 abused to carry the length information from the
6273 alloc_type. Clear it to prevent setting incorrect len
6274 information in future loop iterations. */
6275 if (tmp_expr3_len_flag)
6276 /* No need to reset tmp_expr3_len_flag, because the
6277 presence of an expr3 can not change within in the
6278 loop. */
6279 expr3_len = NULL_TREE;
6281 else if (code->ext.alloc.ts.type == BT_CHARACTER
6282 && code->ext.alloc.ts.u.cl->length)
6284 /* Cover the cases where a string length is explicitly
6285 specified by a type spec for deferred length character
6286 arrays or unlimited polymorphic objects without a
6287 source= or mold= expression. */
6288 if (expr3_esize == NULL_TREE || code->ext.alloc.ts.kind != 1)
6290 gfc_init_se (&se_sz, NULL);
6291 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
6292 gfc_add_block_to_block (&block, &se_sz.pre);
6293 gfc_add_modify (&block, al_len,
6294 fold_convert (TREE_TYPE (al_len),
6295 se_sz.expr));
6297 else
6298 gfc_add_modify (&block, al_len,
6299 fold_convert (TREE_TYPE (al_len),
6300 expr3_esize));
6302 else
6303 /* No length information needed, because type to allocate
6304 has no length. Set _len to 0. */
6305 gfc_add_modify (&block, al_len,
6306 fold_convert (TREE_TYPE (al_len),
6307 integer_zero_node));
6310 init_expr = NULL;
6311 if (code->expr3 && !code->expr3->mold && e3_is != E3_MOLD)
6313 /* Initialization via SOURCE block (or static default initializer).
6314 Switch off automatic reallocation since we have just done the
6315 ALLOCATE. */
6316 int realloc_lhs = flag_realloc_lhs;
6317 gfc_expr *init_expr = gfc_expr_to_initialize (expr);
6318 gfc_expr *rhs = e3rhs ? e3rhs : gfc_copy_expr (code->expr3);
6319 flag_realloc_lhs = 0;
6320 tmp = gfc_trans_assignment (init_expr, rhs, false, false, true,
6321 false);
6322 flag_realloc_lhs = realloc_lhs;
6323 /* Free the expression allocated for init_expr. */
6324 gfc_free_expr (init_expr);
6325 if (rhs != e3rhs)
6326 gfc_free_expr (rhs);
6327 gfc_add_expr_to_block (&block, tmp);
6329 else if (code->expr3 && code->expr3->mold
6330 && code->expr3->ts.type == BT_CLASS)
6332 /* Use class_init_assign to initialize expr. */
6333 gfc_code *ini;
6334 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6335 ini->expr1 = gfc_find_and_cut_at_last_class_ref (expr);
6336 tmp = gfc_trans_class_init_assign (ini);
6337 gfc_free_statements (ini);
6338 gfc_add_expr_to_block (&block, tmp);
6340 else if ((init_expr = allocate_get_initializer (code, expr)))
6342 /* Use class_init_assign to initialize expr. */
6343 gfc_code *ini;
6344 int realloc_lhs = flag_realloc_lhs;
6345 ini = gfc_get_code (EXEC_INIT_ASSIGN);
6346 ini->expr1 = gfc_expr_to_initialize (expr);
6347 ini->expr2 = init_expr;
6348 flag_realloc_lhs = 0;
6349 tmp= gfc_trans_init_assign (ini);
6350 flag_realloc_lhs = realloc_lhs;
6351 gfc_free_statements (ini);
6352 /* Init_expr is freeed by above free_statements, just need to null
6353 it here. */
6354 init_expr = NULL;
6355 gfc_add_expr_to_block (&block, tmp);
6358 /* Nullify all pointers in derived type coarrays. This registers a
6359 token for them which allows their allocation. */
6360 if (is_coarray)
6362 gfc_symbol *type = NULL;
6363 symbol_attribute caf_attr;
6364 int rank = 0;
6365 if (code->ext.alloc.ts.type == BT_DERIVED
6366 && code->ext.alloc.ts.u.derived->attr.pointer_comp)
6368 type = code->ext.alloc.ts.u.derived;
6369 rank = type->attr.dimension ? type->as->rank : 0;
6370 gfc_clear_attr (&caf_attr);
6372 else if (expr->ts.type == BT_DERIVED
6373 && expr->ts.u.derived->attr.pointer_comp)
6375 type = expr->ts.u.derived;
6376 rank = expr->rank;
6377 caf_attr = gfc_caf_attr (expr, true);
6380 /* Initialize the tokens of pointer components in derived type
6381 coarrays. */
6382 if (type)
6384 tmp = (caf_attr.codimension && !caf_attr.dimension)
6385 ? gfc_conv_descriptor_data_get (se.expr) : se.expr;
6386 tmp = gfc_nullify_alloc_comp (type, tmp, rank,
6387 GFC_STRUCTURE_CAF_MODE_IN_COARRAY);
6388 gfc_add_expr_to_block (&block, tmp);
6392 gfc_free_expr (expr);
6393 } // for-loop
6395 if (e3rhs)
6397 if (newsym)
6399 gfc_free_symbol (newsym->n.sym);
6400 XDELETE (newsym);
6402 gfc_free_expr (e3rhs);
6404 /* STAT. */
6405 if (code->expr1)
6407 tmp = build1_v (LABEL_EXPR, label_errmsg);
6408 gfc_add_expr_to_block (&block, tmp);
6411 /* ERRMSG - only useful if STAT is present. */
6412 if (code->expr1 && code->expr2)
6414 const char *msg = "Attempt to allocate an allocated object";
6415 tree slen, dlen, errmsg_str;
6416 stmtblock_t errmsg_block;
6418 gfc_init_block (&errmsg_block);
6420 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6421 gfc_add_modify (&errmsg_block, errmsg_str,
6422 gfc_build_addr_expr (pchar_type_node,
6423 gfc_build_localized_cstring_const (msg)));
6425 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6426 dlen = gfc_get_expr_charlen (code->expr2);
6427 slen = fold_build2_loc (input_location, MIN_EXPR,
6428 TREE_TYPE (slen), dlen, slen);
6430 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
6431 code->expr2->ts.kind,
6432 slen, errmsg_str,
6433 gfc_default_character_kind);
6434 dlen = gfc_finish_block (&errmsg_block);
6436 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
6437 stat, build_int_cst (TREE_TYPE (stat), 0));
6439 tmp = build3_v (COND_EXPR, tmp,
6440 dlen, build_empty_stmt (input_location));
6442 gfc_add_expr_to_block (&block, tmp);
6445 /* STAT block. */
6446 if (code->expr1)
6448 if (TREE_USED (label_finish))
6450 tmp = build1_v (LABEL_EXPR, label_finish);
6451 gfc_add_expr_to_block (&block, tmp);
6454 gfc_init_se (&se, NULL);
6455 gfc_conv_expr_lhs (&se, code->expr1);
6456 tmp = convert (TREE_TYPE (se.expr), stat);
6457 gfc_add_modify (&block, se.expr, tmp);
6460 if (needs_caf_sync)
6462 /* Add a sync all after the allocation has been executed. */
6463 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
6464 3, null_pointer_node, null_pointer_node,
6465 integer_zero_node);
6466 gfc_add_expr_to_block (&post, tmp);
6469 gfc_add_block_to_block (&block, &se.post);
6470 gfc_add_block_to_block (&block, &post);
6472 return gfc_finish_block (&block);
6476 /* Translate a DEALLOCATE statement. */
6478 tree
6479 gfc_trans_deallocate (gfc_code *code)
6481 gfc_se se;
6482 gfc_alloc *al;
6483 tree apstat, pstat, stat, errmsg, errlen, tmp;
6484 tree label_finish, label_errmsg;
6485 stmtblock_t block;
6487 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
6488 label_finish = label_errmsg = NULL_TREE;
6490 gfc_start_block (&block);
6492 /* Count the number of failed deallocations. If deallocate() was
6493 called with STAT= , then set STAT to the count. If deallocate
6494 was called with ERRMSG, then set ERRMG to a string. */
6495 if (code->expr1)
6497 tree gfc_int4_type_node = gfc_get_int_type (4);
6499 stat = gfc_create_var (gfc_int4_type_node, "stat");
6500 pstat = gfc_build_addr_expr (NULL_TREE, stat);
6502 /* GOTO destinations. */
6503 label_errmsg = gfc_build_label_decl (NULL_TREE);
6504 label_finish = gfc_build_label_decl (NULL_TREE);
6505 TREE_USED (label_finish) = 0;
6508 /* Set ERRMSG - only needed if STAT is available. */
6509 if (code->expr1 && code->expr2)
6511 gfc_init_se (&se, NULL);
6512 se.want_pointer = 1;
6513 gfc_conv_expr_lhs (&se, code->expr2);
6514 errmsg = se.expr;
6515 errlen = se.string_length;
6518 for (al = code->ext.alloc.list; al != NULL; al = al->next)
6520 gfc_expr *expr = gfc_copy_expr (al->expr);
6521 bool is_coarray = false, is_coarray_array = false;
6522 int caf_mode = 0;
6524 gcc_assert (expr->expr_type == EXPR_VARIABLE);
6526 if (expr->ts.type == BT_CLASS)
6527 gfc_add_data_component (expr);
6529 gfc_init_se (&se, NULL);
6530 gfc_start_block (&se.pre);
6532 se.want_pointer = 1;
6533 se.descriptor_only = 1;
6534 gfc_conv_expr (&se, expr);
6536 if (flag_coarray == GFC_FCOARRAY_LIB
6537 || flag_coarray == GFC_FCOARRAY_SINGLE)
6539 bool comp_ref;
6540 symbol_attribute caf_attr = gfc_caf_attr (expr, false, &comp_ref);
6541 if (caf_attr.codimension)
6543 is_coarray = true;
6544 is_coarray_array = caf_attr.dimension || !comp_ref
6545 || caf_attr.coarray_comp;
6547 if (flag_coarray == GFC_FCOARRAY_LIB)
6548 /* When the expression to deallocate is referencing a
6549 component, then only deallocate it, but do not
6550 deregister. */
6551 caf_mode = GFC_STRUCTURE_CAF_MODE_IN_COARRAY
6552 | (comp_ref && !caf_attr.coarray_comp
6553 ? GFC_STRUCTURE_CAF_MODE_DEALLOC_ONLY : 0);
6557 if (expr->rank || is_coarray_array)
6559 gfc_ref *ref;
6561 if (gfc_bt_struct (expr->ts.type)
6562 && expr->ts.u.derived->attr.alloc_comp
6563 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
6565 gfc_ref *last = NULL;
6567 for (ref = expr->ref; ref; ref = ref->next)
6568 if (ref->type == REF_COMPONENT)
6569 last = ref;
6571 /* Do not deallocate the components of a derived type
6572 ultimate pointer component. */
6573 if (!(last && last->u.c.component->attr.pointer)
6574 && !(!last && expr->symtree->n.sym->attr.pointer))
6576 if (is_coarray && expr->rank == 0
6577 && (!last || !last->u.c.component->attr.dimension)
6578 && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6580 /* Add the ref to the data member only, when this is not
6581 a regular array or deallocate_alloc_comp will try to
6582 add another one. */
6583 tmp = gfc_conv_descriptor_data_get (se.expr);
6585 else
6586 tmp = se.expr;
6587 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, tmp,
6588 expr->rank, caf_mode);
6589 gfc_add_expr_to_block (&se.pre, tmp);
6593 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
6595 gfc_coarray_deregtype caf_dtype;
6597 if (is_coarray)
6598 caf_dtype = gfc_caf_is_dealloc_only (caf_mode)
6599 ? GFC_CAF_COARRAY_DEALLOCATE_ONLY
6600 : GFC_CAF_COARRAY_DEREGISTER;
6601 else
6602 caf_dtype = GFC_CAF_COARRAY_NOCOARRAY;
6603 tmp = gfc_deallocate_with_status (se.expr, pstat, errmsg, errlen,
6604 label_finish, false, expr,
6605 caf_dtype);
6606 gfc_add_expr_to_block (&se.pre, tmp);
6608 else if (TREE_CODE (se.expr) == COMPONENT_REF
6609 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
6610 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
6611 == RECORD_TYPE)
6613 /* class.c(finalize_component) generates these, when a
6614 finalizable entity has a non-allocatable derived type array
6615 component, which has allocatable components. Obtain the
6616 derived type of the array and deallocate the allocatable
6617 components. */
6618 for (ref = expr->ref; ref; ref = ref->next)
6620 if (ref->u.c.component->attr.dimension
6621 && ref->u.c.component->ts.type == BT_DERIVED)
6622 break;
6625 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
6626 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
6627 NULL))
6629 tmp = gfc_deallocate_alloc_comp
6630 (ref->u.c.component->ts.u.derived,
6631 se.expr, expr->rank);
6632 gfc_add_expr_to_block (&se.pre, tmp);
6636 if (al->expr->ts.type == BT_CLASS)
6638 gfc_reset_vptr (&se.pre, al->expr);
6639 if (UNLIMITED_POLY (al->expr)
6640 || (al->expr->ts.type == BT_DERIVED
6641 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6642 /* Clear _len, too. */
6643 gfc_reset_len (&se.pre, al->expr);
6646 else
6648 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, label_finish,
6649 false, al->expr,
6650 al->expr->ts, is_coarray);
6651 gfc_add_expr_to_block (&se.pre, tmp);
6653 /* Set to zero after deallocation. */
6654 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6655 se.expr,
6656 build_int_cst (TREE_TYPE (se.expr), 0));
6657 gfc_add_expr_to_block (&se.pre, tmp);
6659 if (al->expr->ts.type == BT_CLASS)
6661 gfc_reset_vptr (&se.pre, al->expr);
6662 if (UNLIMITED_POLY (al->expr)
6663 || (al->expr->ts.type == BT_DERIVED
6664 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6665 /* Clear _len, too. */
6666 gfc_reset_len (&se.pre, al->expr);
6670 if (code->expr1)
6672 tree cond;
6674 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6675 build_int_cst (TREE_TYPE (stat), 0));
6676 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6677 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6678 build1_v (GOTO_EXPR, label_errmsg),
6679 build_empty_stmt (input_location));
6680 gfc_add_expr_to_block (&se.pre, tmp);
6683 tmp = gfc_finish_block (&se.pre);
6684 gfc_add_expr_to_block (&block, tmp);
6685 gfc_free_expr (expr);
6688 if (code->expr1)
6690 tmp = build1_v (LABEL_EXPR, label_errmsg);
6691 gfc_add_expr_to_block (&block, tmp);
6694 /* Set ERRMSG - only needed if STAT is available. */
6695 if (code->expr1 && code->expr2)
6697 const char *msg = "Attempt to deallocate an unallocated object";
6698 stmtblock_t errmsg_block;
6699 tree errmsg_str, slen, dlen, cond;
6701 gfc_init_block (&errmsg_block);
6703 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6704 gfc_add_modify (&errmsg_block, errmsg_str,
6705 gfc_build_addr_expr (pchar_type_node,
6706 gfc_build_localized_cstring_const (msg)));
6707 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6708 dlen = gfc_get_expr_charlen (code->expr2);
6710 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6711 slen, errmsg_str, gfc_default_character_kind);
6712 tmp = gfc_finish_block (&errmsg_block);
6714 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6715 build_int_cst (TREE_TYPE (stat), 0));
6716 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6717 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6718 build_empty_stmt (input_location));
6720 gfc_add_expr_to_block (&block, tmp);
6723 if (code->expr1 && TREE_USED (label_finish))
6725 tmp = build1_v (LABEL_EXPR, label_finish);
6726 gfc_add_expr_to_block (&block, tmp);
6729 /* Set STAT. */
6730 if (code->expr1)
6732 gfc_init_se (&se, NULL);
6733 gfc_conv_expr_lhs (&se, code->expr1);
6734 tmp = convert (TREE_TYPE (se.expr), stat);
6735 gfc_add_modify (&block, se.expr, tmp);
6738 return gfc_finish_block (&block);
6741 #include "gt-fortran-trans-stmt.h"