Fix spurious semicolons
[gcc.git] / gcc / fortran / trans-stmt.c
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002-2015 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>. */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "hash-set.h"
27 #include "machmode.h"
28 #include "vec.h"
29 #include "double-int.h"
30 #include "input.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "options.h"
34 #include "wide-int.h"
35 #include "inchash.h"
36 #include "tree.h"
37 #include "fold-const.h"
38 #include "stringpool.h"
39 #include "gfortran.h"
40 #include "flags.h"
41 #include "trans.h"
42 #include "trans-stmt.h"
43 #include "trans-types.h"
44 #include "trans-array.h"
45 #include "trans-const.h"
46 #include "arith.h"
47 #include "dependency.h"
48 #include "ggc.h"
49
50 typedef struct iter_info
51 {
52 tree var;
53 tree start;
54 tree end;
55 tree step;
56 struct iter_info *next;
57 }
58 iter_info;
59
60 typedef struct forall_info
61 {
62 iter_info *this_loop;
63 tree mask;
64 tree maskindex;
65 int nvar;
66 tree size;
67 struct forall_info *prev_nest;
68 bool do_concurrent;
69 }
70 forall_info;
71
72 static void gfc_trans_where_2 (gfc_code *, tree, bool,
73 forall_info *, stmtblock_t *);
74
75 /* Translate a F95 label number to a LABEL_EXPR. */
76
77 tree
78 gfc_trans_label_here (gfc_code * code)
79 {
80 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
81 }
82
83
84 /* Given a variable expression which has been ASSIGNed to, find the decl
85 containing the auxiliary variables. For variables in common blocks this
86 is a field_decl. */
87
88 void
89 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
90 {
91 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
92 gfc_conv_expr (se, expr);
93 /* Deals with variable in common block. Get the field declaration. */
94 if (TREE_CODE (se->expr) == COMPONENT_REF)
95 se->expr = TREE_OPERAND (se->expr, 1);
96 /* Deals with dummy argument. Get the parameter declaration. */
97 else if (TREE_CODE (se->expr) == INDIRECT_REF)
98 se->expr = TREE_OPERAND (se->expr, 0);
99 }
100
101 /* Translate a label assignment statement. */
102
103 tree
104 gfc_trans_label_assign (gfc_code * code)
105 {
106 tree label_tree;
107 gfc_se se;
108 tree len;
109 tree addr;
110 tree len_tree;
111 int label_len;
112
113 /* Start a new block. */
114 gfc_init_se (&se, NULL);
115 gfc_start_block (&se.pre);
116 gfc_conv_label_variable (&se, code->expr1);
117
118 len = GFC_DECL_STRING_LEN (se.expr);
119 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
120
121 label_tree = gfc_get_label_decl (code->label1);
122
123 if (code->label1->defined == ST_LABEL_TARGET
124 || code->label1->defined == ST_LABEL_DO_TARGET)
125 {
126 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
127 len_tree = integer_minus_one_node;
128 }
129 else
130 {
131 gfc_expr *format = code->label1->format;
132
133 label_len = format->value.character.length;
134 len_tree = build_int_cst (gfc_charlen_type_node, label_len);
135 label_tree = gfc_build_wide_string_const (format->ts.kind, label_len + 1,
136 format->value.character.string);
137 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
138 }
139
140 gfc_add_modify (&se.pre, len, len_tree);
141 gfc_add_modify (&se.pre, addr, label_tree);
142
143 return gfc_finish_block (&se.pre);
144 }
145
146 /* Translate a GOTO statement. */
147
148 tree
149 gfc_trans_goto (gfc_code * code)
150 {
151 locus loc = code->loc;
152 tree assigned_goto;
153 tree target;
154 tree tmp;
155 gfc_se se;
156
157 if (code->label1 != NULL)
158 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
159
160 /* ASSIGNED GOTO. */
161 gfc_init_se (&se, NULL);
162 gfc_start_block (&se.pre);
163 gfc_conv_label_variable (&se, code->expr1);
164 tmp = GFC_DECL_STRING_LEN (se.expr);
165 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
166 build_int_cst (TREE_TYPE (tmp), -1));
167 gfc_trans_runtime_check (true, false, tmp, &se.pre, &loc,
168 "Assigned label is not a target label");
169
170 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
171
172 /* We're going to ignore a label list. It does not really change the
173 statement's semantics (because it is just a further restriction on
174 what's legal code); before, we were comparing label addresses here, but
175 that's a very fragile business and may break with optimization. So
176 just ignore it. */
177
178 target = fold_build1_loc (input_location, GOTO_EXPR, void_type_node,
179 assigned_goto);
180 gfc_add_expr_to_block (&se.pre, target);
181 return gfc_finish_block (&se.pre);
182 }
183
184
185 /* Translate an ENTRY statement. Just adds a label for this entry point. */
186 tree
187 gfc_trans_entry (gfc_code * code)
188 {
189 return build1_v (LABEL_EXPR, code->ext.entry->label);
190 }
191
192
193 /* Replace a gfc_ss structure by another both in the gfc_se struct
194 and the gfc_loopinfo struct. This is used in gfc_conv_elemental_dependencies
195 to replace a variable ss by the corresponding temporary. */
196
197 static void
198 replace_ss (gfc_se *se, gfc_ss *old_ss, gfc_ss *new_ss)
199 {
200 gfc_ss **sess, **loopss;
201
202 /* The old_ss is a ss for a single variable. */
203 gcc_assert (old_ss->info->type == GFC_SS_SECTION);
204
205 for (sess = &(se->ss); *sess != gfc_ss_terminator; sess = &((*sess)->next))
206 if (*sess == old_ss)
207 break;
208 gcc_assert (*sess != gfc_ss_terminator);
209
210 *sess = new_ss;
211 new_ss->next = old_ss->next;
212
213
214 for (loopss = &(se->loop->ss); *loopss != gfc_ss_terminator;
215 loopss = &((*loopss)->loop_chain))
216 if (*loopss == old_ss)
217 break;
218 gcc_assert (*loopss != gfc_ss_terminator);
219
220 *loopss = new_ss;
221 new_ss->loop_chain = old_ss->loop_chain;
222 new_ss->loop = old_ss->loop;
223
224 gfc_free_ss (old_ss);
225 }
226
227
228 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
229 elemental subroutines. Make temporaries for output arguments if any such
230 dependencies are found. Output arguments are chosen because internal_unpack
231 can be used, as is, to copy the result back to the variable. */
232 static void
233 gfc_conv_elemental_dependencies (gfc_se * se, gfc_se * loopse,
234 gfc_symbol * sym, gfc_actual_arglist * arg,
235 gfc_dep_check check_variable)
236 {
237 gfc_actual_arglist *arg0;
238 gfc_expr *e;
239 gfc_formal_arglist *formal;
240 gfc_se parmse;
241 gfc_ss *ss;
242 gfc_symbol *fsym;
243 tree data;
244 tree size;
245 tree tmp;
246
247 if (loopse->ss == NULL)
248 return;
249
250 ss = loopse->ss;
251 arg0 = arg;
252 formal = gfc_sym_get_dummy_args (sym);
253
254 /* Loop over all the arguments testing for dependencies. */
255 for (; arg != NULL; arg = arg->next, formal = formal ? formal->next : NULL)
256 {
257 e = arg->expr;
258 if (e == NULL)
259 continue;
260
261 /* Obtain the info structure for the current argument. */
262 for (ss = loopse->ss; ss && ss != gfc_ss_terminator; ss = ss->next)
263 if (ss->info->expr == e)
264 break;
265
266 /* If there is a dependency, create a temporary and use it
267 instead of the variable. */
268 fsym = formal ? formal->sym : NULL;
269 if (e->expr_type == EXPR_VARIABLE
270 && e->rank && fsym
271 && fsym->attr.intent != INTENT_IN
272 && gfc_check_fncall_dependency (e, fsym->attr.intent,
273 sym, arg0, check_variable))
274 {
275 tree initial, temptype;
276 stmtblock_t temp_post;
277 gfc_ss *tmp_ss;
278
279 tmp_ss = gfc_get_array_ss (gfc_ss_terminator, NULL, ss->dimen,
280 GFC_SS_SECTION);
281 gfc_mark_ss_chain_used (tmp_ss, 1);
282 tmp_ss->info->expr = ss->info->expr;
283 replace_ss (loopse, ss, tmp_ss);
284
285 /* Obtain the argument descriptor for unpacking. */
286 gfc_init_se (&parmse, NULL);
287 parmse.want_pointer = 1;
288 gfc_conv_expr_descriptor (&parmse, e);
289 gfc_add_block_to_block (&se->pre, &parmse.pre);
290
291 /* If we've got INTENT(INOUT) or a derived type with INTENT(OUT),
292 initialize the array temporary with a copy of the values. */
293 if (fsym->attr.intent == INTENT_INOUT
294 || (fsym->ts.type ==BT_DERIVED
295 && fsym->attr.intent == INTENT_OUT))
296 initial = parmse.expr;
297 /* For class expressions, we always initialize with the copy of
298 the values. */
299 else if (e->ts.type == BT_CLASS)
300 initial = parmse.expr;
301 else
302 initial = NULL_TREE;
303
304 if (e->ts.type != BT_CLASS)
305 {
306 /* Find the type of the temporary to create; we don't use the type
307 of e itself as this breaks for subcomponent-references in e
308 (where the type of e is that of the final reference, but
309 parmse.expr's type corresponds to the full derived-type). */
310 /* TODO: Fix this somehow so we don't need a temporary of the whole
311 array but instead only the components referenced. */
312 temptype = TREE_TYPE (parmse.expr); /* Pointer to descriptor. */
313 gcc_assert (TREE_CODE (temptype) == POINTER_TYPE);
314 temptype = TREE_TYPE (temptype);
315 temptype = gfc_get_element_type (temptype);
316 }
317
318 else
319 /* For class arrays signal that the size of the dynamic type has to
320 be obtained from the vtable, using the 'initial' expression. */
321 temptype = NULL_TREE;
322
323 /* Generate the temporary. Cleaning up the temporary should be the
324 very last thing done, so we add the code to a new block and add it
325 to se->post as last instructions. */
326 size = gfc_create_var (gfc_array_index_type, NULL);
327 data = gfc_create_var (pvoid_type_node, NULL);
328 gfc_init_block (&temp_post);
329 tmp = gfc_trans_create_temp_array (&se->pre, &temp_post, tmp_ss,
330 temptype, initial, false, true,
331 false, &arg->expr->where);
332 gfc_add_modify (&se->pre, size, tmp);
333 tmp = fold_convert (pvoid_type_node, tmp_ss->info->data.array.data);
334 gfc_add_modify (&se->pre, data, tmp);
335
336 /* Update other ss' delta. */
337 gfc_set_delta (loopse->loop);
338
339 /* Copy the result back using unpack..... */
340 if (e->ts.type != BT_CLASS)
341 tmp = build_call_expr_loc (input_location,
342 gfor_fndecl_in_unpack, 2, parmse.expr, data);
343 else
344 {
345 /* ... except for class results where the copy is
346 unconditional. */
347 tmp = build_fold_indirect_ref_loc (input_location, parmse.expr);
348 tmp = gfc_conv_descriptor_data_get (tmp);
349 tmp = build_call_expr_loc (input_location,
350 builtin_decl_explicit (BUILT_IN_MEMCPY),
351 3, tmp, data,
352 fold_convert (size_type_node, size));
353 }
354 gfc_add_expr_to_block (&se->post, tmp);
355
356 /* parmse.pre is already added above. */
357 gfc_add_block_to_block (&se->post, &parmse.post);
358 gfc_add_block_to_block (&se->post, &temp_post);
359 }
360 }
361 }
362
363
364 /* Get the interface symbol for the procedure corresponding to the given call.
365 We can't get the procedure symbol directly as we have to handle the case
366 of (deferred) type-bound procedures. */
367
368 static gfc_symbol *
369 get_proc_ifc_for_call (gfc_code *c)
370 {
371 gfc_symbol *sym;
372
373 gcc_assert (c->op == EXEC_ASSIGN_CALL || c->op == EXEC_CALL);
374
375 sym = gfc_get_proc_ifc_for_expr (c->expr1);
376
377 /* Fall back/last resort try. */
378 if (sym == NULL)
379 sym = c->resolved_sym;
380
381 return sym;
382 }
383
384
385 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
386
387 tree
388 gfc_trans_call (gfc_code * code, bool dependency_check,
389 tree mask, tree count1, bool invert)
390 {
391 gfc_se se;
392 gfc_ss * ss;
393 int has_alternate_specifier;
394 gfc_dep_check check_variable;
395 tree index = NULL_TREE;
396 tree maskexpr = NULL_TREE;
397 tree tmp;
398
399 /* A CALL starts a new block because the actual arguments may have to
400 be evaluated first. */
401 gfc_init_se (&se, NULL);
402 gfc_start_block (&se.pre);
403
404 gcc_assert (code->resolved_sym);
405
406 ss = gfc_ss_terminator;
407 if (code->resolved_sym->attr.elemental)
408 ss = gfc_walk_elemental_function_args (ss, code->ext.actual,
409 get_proc_ifc_for_call (code),
410 GFC_SS_REFERENCE);
411
412 /* Is not an elemental subroutine call with array valued arguments. */
413 if (ss == gfc_ss_terminator)
414 {
415
416 /* Translate the call. */
417 has_alternate_specifier
418 = gfc_conv_procedure_call (&se, code->resolved_sym, code->ext.actual,
419 code->expr1, NULL);
420
421 /* A subroutine without side-effect, by definition, does nothing! */
422 TREE_SIDE_EFFECTS (se.expr) = 1;
423
424 /* Chain the pieces together and return the block. */
425 if (has_alternate_specifier)
426 {
427 gfc_code *select_code;
428 gfc_symbol *sym;
429 select_code = code->next;
430 gcc_assert(select_code->op == EXEC_SELECT);
431 sym = select_code->expr1->symtree->n.sym;
432 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
433 if (sym->backend_decl == NULL)
434 sym->backend_decl = gfc_get_symbol_decl (sym);
435 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
436 }
437 else
438 gfc_add_expr_to_block (&se.pre, se.expr);
439
440 gfc_add_block_to_block (&se.pre, &se.post);
441 }
442
443 else
444 {
445 /* An elemental subroutine call with array valued arguments has
446 to be scalarized. */
447 gfc_loopinfo loop;
448 stmtblock_t body;
449 stmtblock_t block;
450 gfc_se loopse;
451 gfc_se depse;
452
453 /* gfc_walk_elemental_function_args renders the ss chain in the
454 reverse order to the actual argument order. */
455 ss = gfc_reverse_ss (ss);
456
457 /* Initialize the loop. */
458 gfc_init_se (&loopse, NULL);
459 gfc_init_loopinfo (&loop);
460 gfc_add_ss_to_loop (&loop, ss);
461
462 gfc_conv_ss_startstride (&loop);
463 /* TODO: gfc_conv_loop_setup generates a temporary for vector
464 subscripts. This could be prevented in the elemental case
465 as temporaries are handled separatedly
466 (below in gfc_conv_elemental_dependencies). */
467 gfc_conv_loop_setup (&loop, &code->expr1->where);
468 gfc_mark_ss_chain_used (ss, 1);
469
470 /* Convert the arguments, checking for dependencies. */
471 gfc_copy_loopinfo_to_se (&loopse, &loop);
472 loopse.ss = ss;
473
474 /* For operator assignment, do dependency checking. */
475 if (dependency_check)
476 check_variable = ELEM_CHECK_VARIABLE;
477 else
478 check_variable = ELEM_DONT_CHECK_VARIABLE;
479
480 gfc_init_se (&depse, NULL);
481 gfc_conv_elemental_dependencies (&depse, &loopse, code->resolved_sym,
482 code->ext.actual, check_variable);
483
484 gfc_add_block_to_block (&loop.pre, &depse.pre);
485 gfc_add_block_to_block (&loop.post, &depse.post);
486
487 /* Generate the loop body. */
488 gfc_start_scalarized_body (&loop, &body);
489 gfc_init_block (&block);
490
491 if (mask && count1)
492 {
493 /* Form the mask expression according to the mask. */
494 index = count1;
495 maskexpr = gfc_build_array_ref (mask, index, NULL);
496 if (invert)
497 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
498 TREE_TYPE (maskexpr), maskexpr);
499 }
500
501 /* Add the subroutine call to the block. */
502 gfc_conv_procedure_call (&loopse, code->resolved_sym,
503 code->ext.actual, code->expr1,
504 NULL);
505
506 if (mask && count1)
507 {
508 tmp = build3_v (COND_EXPR, maskexpr, loopse.expr,
509 build_empty_stmt (input_location));
510 gfc_add_expr_to_block (&loopse.pre, tmp);
511 tmp = fold_build2_loc (input_location, PLUS_EXPR,
512 gfc_array_index_type,
513 count1, gfc_index_one_node);
514 gfc_add_modify (&loopse.pre, count1, tmp);
515 }
516 else
517 gfc_add_expr_to_block (&loopse.pre, loopse.expr);
518
519 gfc_add_block_to_block (&block, &loopse.pre);
520 gfc_add_block_to_block (&block, &loopse.post);
521
522 /* Finish up the loop block and the loop. */
523 gfc_add_expr_to_block (&body, gfc_finish_block (&block));
524 gfc_trans_scalarizing_loops (&loop, &body);
525 gfc_add_block_to_block (&se.pre, &loop.pre);
526 gfc_add_block_to_block (&se.pre, &loop.post);
527 gfc_add_block_to_block (&se.pre, &se.post);
528 gfc_cleanup_loop (&loop);
529 }
530
531 return gfc_finish_block (&se.pre);
532 }
533
534
535 /* Translate the RETURN statement. */
536
537 tree
538 gfc_trans_return (gfc_code * code)
539 {
540 if (code->expr1)
541 {
542 gfc_se se;
543 tree tmp;
544 tree result;
545
546 /* If code->expr is not NULL, this return statement must appear
547 in a subroutine and current_fake_result_decl has already
548 been generated. */
549
550 result = gfc_get_fake_result_decl (NULL, 0);
551 if (!result)
552 {
553 gfc_warning (0,
554 "An alternate return at %L without a * dummy argument",
555 &code->expr1->where);
556 return gfc_generate_return ();
557 }
558
559 /* Start a new block for this statement. */
560 gfc_init_se (&se, NULL);
561 gfc_start_block (&se.pre);
562
563 gfc_conv_expr (&se, code->expr1);
564
565 /* Note that the actually returned expression is a simple value and
566 does not depend on any pointers or such; thus we can clean-up with
567 se.post before returning. */
568 tmp = fold_build2_loc (input_location, MODIFY_EXPR, TREE_TYPE (result),
569 result, fold_convert (TREE_TYPE (result),
570 se.expr));
571 gfc_add_expr_to_block (&se.pre, tmp);
572 gfc_add_block_to_block (&se.pre, &se.post);
573
574 tmp = gfc_generate_return ();
575 gfc_add_expr_to_block (&se.pre, tmp);
576 return gfc_finish_block (&se.pre);
577 }
578
579 return gfc_generate_return ();
580 }
581
582
583 /* Translate the PAUSE statement. We have to translate this statement
584 to a runtime library call. */
585
586 tree
587 gfc_trans_pause (gfc_code * code)
588 {
589 tree gfc_int4_type_node = gfc_get_int_type (4);
590 gfc_se se;
591 tree tmp;
592
593 /* Start a new block for this statement. */
594 gfc_init_se (&se, NULL);
595 gfc_start_block (&se.pre);
596
597
598 if (code->expr1 == NULL)
599 {
600 tmp = build_int_cst (gfc_int4_type_node, 0);
601 tmp = build_call_expr_loc (input_location,
602 gfor_fndecl_pause_string, 2,
603 build_int_cst (pchar_type_node, 0), tmp);
604 }
605 else if (code->expr1->ts.type == BT_INTEGER)
606 {
607 gfc_conv_expr (&se, code->expr1);
608 tmp = build_call_expr_loc (input_location,
609 gfor_fndecl_pause_numeric, 1,
610 fold_convert (gfc_int4_type_node, se.expr));
611 }
612 else
613 {
614 gfc_conv_expr_reference (&se, code->expr1);
615 tmp = build_call_expr_loc (input_location,
616 gfor_fndecl_pause_string, 2,
617 se.expr, se.string_length);
618 }
619
620 gfc_add_expr_to_block (&se.pre, tmp);
621
622 gfc_add_block_to_block (&se.pre, &se.post);
623
624 return gfc_finish_block (&se.pre);
625 }
626
627
628 /* Translate the STOP statement. We have to translate this statement
629 to a runtime library call. */
630
631 tree
632 gfc_trans_stop (gfc_code *code, bool error_stop)
633 {
634 tree gfc_int4_type_node = gfc_get_int_type (4);
635 gfc_se se;
636 tree tmp;
637
638 /* Start a new block for this statement. */
639 gfc_init_se (&se, NULL);
640 gfc_start_block (&se.pre);
641
642 if (code->expr1 == NULL)
643 {
644 tmp = build_int_cst (gfc_int4_type_node, 0);
645 tmp = build_call_expr_loc (input_location,
646 error_stop
647 ? (flag_coarray == GFC_FCOARRAY_LIB
648 ? gfor_fndecl_caf_error_stop_str
649 : gfor_fndecl_error_stop_string)
650 : gfor_fndecl_stop_string,
651 2, build_int_cst (pchar_type_node, 0), tmp);
652 }
653 else if (code->expr1->ts.type == BT_INTEGER)
654 {
655 gfc_conv_expr (&se, code->expr1);
656 tmp = build_call_expr_loc (input_location,
657 error_stop
658 ? (flag_coarray == GFC_FCOARRAY_LIB
659 ? gfor_fndecl_caf_error_stop
660 : gfor_fndecl_error_stop_numeric)
661 : gfor_fndecl_stop_numeric_f08, 1,
662 fold_convert (gfc_int4_type_node, se.expr));
663 }
664 else
665 {
666 gfc_conv_expr_reference (&se, code->expr1);
667 tmp = build_call_expr_loc (input_location,
668 error_stop
669 ? (flag_coarray == GFC_FCOARRAY_LIB
670 ? gfor_fndecl_caf_error_stop_str
671 : gfor_fndecl_error_stop_string)
672 : gfor_fndecl_stop_string,
673 2, se.expr, se.string_length);
674 }
675
676 gfc_add_expr_to_block (&se.pre, tmp);
677
678 gfc_add_block_to_block (&se.pre, &se.post);
679
680 return gfc_finish_block (&se.pre);
681 }
682
683
684 tree
685 gfc_trans_lock_unlock (gfc_code *code, gfc_exec_op op)
686 {
687 gfc_se se, argse;
688 tree stat = NULL_TREE, stat2 = NULL_TREE;
689 tree lock_acquired = NULL_TREE, lock_acquired2 = NULL_TREE;
690
691 /* Short cut: For single images without STAT= or LOCK_ACQUIRED
692 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
693 if (!code->expr2 && !code->expr4 && flag_coarray != GFC_FCOARRAY_LIB)
694 return NULL_TREE;
695
696 if (code->expr2)
697 {
698 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
699 gfc_init_se (&argse, NULL);
700 gfc_conv_expr_val (&argse, code->expr2);
701 stat = argse.expr;
702 }
703 else if (flag_coarray == GFC_FCOARRAY_LIB)
704 stat = null_pointer_node;
705
706 if (code->expr4)
707 {
708 gcc_assert (code->expr4->expr_type == EXPR_VARIABLE);
709 gfc_init_se (&argse, NULL);
710 gfc_conv_expr_val (&argse, code->expr4);
711 lock_acquired = argse.expr;
712 }
713 else if (flag_coarray == GFC_FCOARRAY_LIB)
714 lock_acquired = null_pointer_node;
715
716 gfc_start_block (&se.pre);
717 if (flag_coarray == GFC_FCOARRAY_LIB)
718 {
719 tree tmp, token, image_index, errmsg, errmsg_len;
720 tree index = size_zero_node;
721 tree caf_decl = gfc_get_tree_for_caf_expr (code->expr1);
722
723 if (code->expr1->symtree->n.sym->ts.type != BT_DERIVED
724 || code->expr1->symtree->n.sym->ts.u.derived->from_intmod
725 != INTMOD_ISO_FORTRAN_ENV
726 || code->expr1->symtree->n.sym->ts.u.derived->intmod_sym_id
727 != ISOFORTRAN_LOCK_TYPE)
728 {
729 gfc_error ("Sorry, the lock component of derived type at %L is not "
730 "yet supported", &code->expr1->where);
731 return NULL_TREE;
732 }
733
734 gfc_get_caf_token_offset (&token, NULL, caf_decl, NULL_TREE, code->expr1);
735
736 if (gfc_is_coindexed (code->expr1))
737 image_index = gfc_caf_get_image_index (&se.pre, code->expr1, caf_decl);
738 else
739 image_index = integer_zero_node;
740
741 /* For arrays, obtain the array index. */
742 if (gfc_expr_attr (code->expr1).dimension)
743 {
744 tree desc, tmp, extent, lbound, ubound;
745 gfc_array_ref *ar, ar2;
746 int i;
747
748 /* TODO: Extend this, once DT components are supported. */
749 ar = &code->expr1->ref->u.ar;
750 ar2 = *ar;
751 memset (ar, '\0', sizeof (*ar));
752 ar->as = ar2.as;
753 ar->type = AR_FULL;
754
755 gfc_init_se (&argse, NULL);
756 argse.descriptor_only = 1;
757 gfc_conv_expr_descriptor (&argse, code->expr1);
758 gfc_add_block_to_block (&se.pre, &argse.pre);
759 desc = argse.expr;
760 *ar = ar2;
761
762 extent = integer_one_node;
763 for (i = 0; i < ar->dimen; i++)
764 {
765 gfc_init_se (&argse, NULL);
766 gfc_conv_expr_type (&argse, ar->start[i], integer_type_node);
767 gfc_add_block_to_block (&argse.pre, &argse.pre);
768 lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
769 tmp = fold_build2_loc (input_location, MINUS_EXPR,
770 integer_type_node, argse.expr,
771 fold_convert(integer_type_node, lbound));
772 tmp = fold_build2_loc (input_location, MULT_EXPR,
773 integer_type_node, extent, tmp);
774 index = fold_build2_loc (input_location, PLUS_EXPR,
775 integer_type_node, index, tmp);
776 if (i < ar->dimen - 1)
777 {
778 ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
779 tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
780 tmp = fold_convert (integer_type_node, tmp);
781 extent = fold_build2_loc (input_location, MULT_EXPR,
782 integer_type_node, extent, tmp);
783 }
784 }
785 }
786
787 /* errmsg. */
788 if (code->expr3)
789 {
790 gfc_init_se (&argse, NULL);
791 gfc_conv_expr (&argse, code->expr3);
792 gfc_add_block_to_block (&se.pre, &argse.pre);
793 errmsg = argse.expr;
794 errmsg_len = fold_convert (integer_type_node, argse.string_length);
795 }
796 else
797 {
798 errmsg = null_pointer_node;
799 errmsg_len = integer_zero_node;
800 }
801
802 if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
803 {
804 stat2 = stat;
805 stat = gfc_create_var (integer_type_node, "stat");
806 }
807
808 if (lock_acquired != null_pointer_node
809 && TREE_TYPE (lock_acquired) != integer_type_node)
810 {
811 lock_acquired2 = lock_acquired;
812 lock_acquired = gfc_create_var (integer_type_node, "acquired");
813 }
814
815 if (op == EXEC_LOCK)
816 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
817 token, index, image_index,
818 lock_acquired != null_pointer_node
819 ? gfc_build_addr_expr (NULL, lock_acquired)
820 : lock_acquired,
821 stat != null_pointer_node
822 ? gfc_build_addr_expr (NULL, stat) : stat,
823 errmsg, errmsg_len);
824 else
825 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
826 token, index, image_index,
827 stat != null_pointer_node
828 ? gfc_build_addr_expr (NULL, stat) : stat,
829 errmsg, errmsg_len);
830 gfc_add_expr_to_block (&se.pre, tmp);
831
832 if (stat2 != NULL_TREE)
833 gfc_add_modify (&se.pre, stat2,
834 fold_convert (TREE_TYPE (stat2), stat));
835
836 if (lock_acquired2 != NULL_TREE)
837 gfc_add_modify (&se.pre, lock_acquired2,
838 fold_convert (TREE_TYPE (lock_acquired2),
839 lock_acquired));
840
841 return gfc_finish_block (&se.pre);
842 }
843
844 if (stat != NULL_TREE)
845 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
846
847 if (lock_acquired != NULL_TREE)
848 gfc_add_modify (&se.pre, lock_acquired,
849 fold_convert (TREE_TYPE (lock_acquired),
850 boolean_true_node));
851
852 return gfc_finish_block (&se.pre);
853 }
854
855
856 tree
857 gfc_trans_sync (gfc_code *code, gfc_exec_op type)
858 {
859 gfc_se se, argse;
860 tree tmp;
861 tree images = NULL_TREE, stat = NULL_TREE,
862 errmsg = NULL_TREE, errmsglen = NULL_TREE;
863
864 /* Short cut: For single images without bound checking or without STAT=,
865 return early. (ERRMSG= is always untouched for -fcoarray=single.) */
866 if (!code->expr2 && !(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
867 && flag_coarray != GFC_FCOARRAY_LIB)
868 return NULL_TREE;
869
870 gfc_init_se (&se, NULL);
871 gfc_start_block (&se.pre);
872
873 if (code->expr1 && code->expr1->rank == 0)
874 {
875 gfc_init_se (&argse, NULL);
876 gfc_conv_expr_val (&argse, code->expr1);
877 images = argse.expr;
878 }
879
880 if (code->expr2)
881 {
882 gcc_assert (code->expr2->expr_type == EXPR_VARIABLE);
883 gfc_init_se (&argse, NULL);
884 gfc_conv_expr_val (&argse, code->expr2);
885 stat = argse.expr;
886 }
887 else
888 stat = null_pointer_node;
889
890 if (code->expr3 && flag_coarray == GFC_FCOARRAY_LIB)
891 {
892 gcc_assert (code->expr3->expr_type == EXPR_VARIABLE);
893 gfc_init_se (&argse, NULL);
894 gfc_conv_expr (&argse, code->expr3);
895 gfc_conv_string_parameter (&argse);
896 errmsg = gfc_build_addr_expr (NULL, argse.expr);
897 errmsglen = argse.string_length;
898 }
899 else if (flag_coarray == GFC_FCOARRAY_LIB)
900 {
901 errmsg = null_pointer_node;
902 errmsglen = build_int_cst (integer_type_node, 0);
903 }
904
905 /* Check SYNC IMAGES(imageset) for valid image index.
906 FIXME: Add a check for image-set arrays. */
907 if (code->expr1 && (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
908 && code->expr1->rank == 0)
909 {
910 tree cond;
911 if (flag_coarray != GFC_FCOARRAY_LIB)
912 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
913 images, build_int_cst (TREE_TYPE (images), 1));
914 else
915 {
916 tree cond2;
917 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
918 2, integer_zero_node,
919 build_int_cst (integer_type_node, -1));
920 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
921 images, tmp);
922 cond2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
923 images,
924 build_int_cst (TREE_TYPE (images), 1));
925 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
926 boolean_type_node, cond, cond2);
927 }
928 gfc_trans_runtime_check (true, false, cond, &se.pre,
929 &code->expr1->where, "Invalid image number "
930 "%d in SYNC IMAGES",
931 fold_convert (integer_type_node, images));
932 }
933
934 if (flag_coarray != GFC_FCOARRAY_LIB)
935 {
936 /* Set STAT to zero. */
937 if (code->expr2)
938 gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));
939 }
940 else if (type == EXEC_SYNC_ALL || type == EXEC_SYNC_MEMORY)
941 {
942 /* SYNC ALL => stat == null_pointer_node
943 SYNC ALL(stat=s) => stat has an integer type
944
945 If "stat" has the wrong integer type, use a temp variable of
946 the right type and later cast the result back into "stat". */
947 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
948 {
949 if (TREE_TYPE (stat) == integer_type_node)
950 stat = gfc_build_addr_expr (NULL, stat);
951
952 if(type == EXEC_SYNC_MEMORY)
953 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_memory,
954 3, stat, errmsg, errmsglen);
955 else
956 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
957 3, stat, errmsg, errmsglen);
958
959 gfc_add_expr_to_block (&se.pre, tmp);
960 }
961 else
962 {
963 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
964
965 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
966 3, gfc_build_addr_expr (NULL, tmp_stat),
967 errmsg, errmsglen);
968 gfc_add_expr_to_block (&se.pre, tmp);
969
970 gfc_add_modify (&se.pre, stat,
971 fold_convert (TREE_TYPE (stat), tmp_stat));
972 }
973 }
974 else
975 {
976 tree len;
977
978 gcc_assert (type == EXEC_SYNC_IMAGES);
979
980 if (!code->expr1)
981 {
982 len = build_int_cst (integer_type_node, -1);
983 images = null_pointer_node;
984 }
985 else if (code->expr1->rank == 0)
986 {
987 len = build_int_cst (integer_type_node, 1);
988 images = gfc_build_addr_expr (NULL_TREE, images);
989 }
990 else
991 {
992 /* FIXME. */
993 if (code->expr1->ts.kind != gfc_c_int_kind)
994 gfc_fatal_error ("Sorry, only support for integer kind %d "
995 "implemented for image-set at %L",
996 gfc_c_int_kind, &code->expr1->where);
997
998 gfc_conv_array_parameter (&se, code->expr1, true, NULL, NULL, &len);
999 images = se.expr;
1000
1001 tmp = gfc_typenode_for_spec (&code->expr1->ts);
1002 if (GFC_ARRAY_TYPE_P (tmp) || GFC_DESCRIPTOR_TYPE_P (tmp))
1003 tmp = gfc_get_element_type (tmp);
1004
1005 len = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1006 TREE_TYPE (len), len,
1007 fold_convert (TREE_TYPE (len),
1008 TYPE_SIZE_UNIT (tmp)));
1009 len = fold_convert (integer_type_node, len);
1010 }
1011
1012 /* SYNC IMAGES(imgs) => stat == null_pointer_node
1013 SYNC IMAGES(imgs,stat=s) => stat has an integer type
1014
1015 If "stat" has the wrong integer type, use a temp variable of
1016 the right type and later cast the result back into "stat". */
1017 if (stat == null_pointer_node || TREE_TYPE (stat) == integer_type_node)
1018 {
1019 if (TREE_TYPE (stat) == integer_type_node)
1020 stat = gfc_build_addr_expr (NULL, stat);
1021
1022 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1023 5, fold_convert (integer_type_node, len),
1024 images, stat, errmsg, errmsglen);
1025 gfc_add_expr_to_block (&se.pre, tmp);
1026 }
1027 else
1028 {
1029 tree tmp_stat = gfc_create_var (integer_type_node, "stat");
1030
1031 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_images,
1032 5, fold_convert (integer_type_node, len),
1033 images, gfc_build_addr_expr (NULL, tmp_stat),
1034 errmsg, errmsglen);
1035 gfc_add_expr_to_block (&se.pre, tmp);
1036
1037 gfc_add_modify (&se.pre, stat,
1038 fold_convert (TREE_TYPE (stat), tmp_stat));
1039 }
1040 }
1041
1042 return gfc_finish_block (&se.pre);
1043 }
1044
1045
1046 /* Generate GENERIC for the IF construct. This function also deals with
1047 the simple IF statement, because the front end translates the IF
1048 statement into an IF construct.
1049
1050 We translate:
1051
1052 IF (cond) THEN
1053 then_clause
1054 ELSEIF (cond2)
1055 elseif_clause
1056 ELSE
1057 else_clause
1058 ENDIF
1059
1060 into:
1061
1062 pre_cond_s;
1063 if (cond_s)
1064 {
1065 then_clause;
1066 }
1067 else
1068 {
1069 pre_cond_s
1070 if (cond_s)
1071 {
1072 elseif_clause
1073 }
1074 else
1075 {
1076 else_clause;
1077 }
1078 }
1079
1080 where COND_S is the simplified version of the predicate. PRE_COND_S
1081 are the pre side-effects produced by the translation of the
1082 conditional.
1083 We need to build the chain recursively otherwise we run into
1084 problems with folding incomplete statements. */
1085
1086 static tree
1087 gfc_trans_if_1 (gfc_code * code)
1088 {
1089 gfc_se if_se;
1090 tree stmt, elsestmt;
1091 locus saved_loc;
1092 location_t loc;
1093
1094 /* Check for an unconditional ELSE clause. */
1095 if (!code->expr1)
1096 return gfc_trans_code (code->next);
1097
1098 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
1099 gfc_init_se (&if_se, NULL);
1100 gfc_start_block (&if_se.pre);
1101
1102 /* Calculate the IF condition expression. */
1103 if (code->expr1->where.lb)
1104 {
1105 gfc_save_backend_locus (&saved_loc);
1106 gfc_set_backend_locus (&code->expr1->where);
1107 }
1108
1109 gfc_conv_expr_val (&if_se, code->expr1);
1110
1111 if (code->expr1->where.lb)
1112 gfc_restore_backend_locus (&saved_loc);
1113
1114 /* Translate the THEN clause. */
1115 stmt = gfc_trans_code (code->next);
1116
1117 /* Translate the ELSE clause. */
1118 if (code->block)
1119 elsestmt = gfc_trans_if_1 (code->block);
1120 else
1121 elsestmt = build_empty_stmt (input_location);
1122
1123 /* Build the condition expression and add it to the condition block. */
1124 loc = code->expr1->where.lb ? code->expr1->where.lb->location : input_location;
1125 stmt = fold_build3_loc (loc, COND_EXPR, void_type_node, if_se.expr, stmt,
1126 elsestmt);
1127
1128 gfc_add_expr_to_block (&if_se.pre, stmt);
1129
1130 /* Finish off this statement. */
1131 return gfc_finish_block (&if_se.pre);
1132 }
1133
1134 tree
1135 gfc_trans_if (gfc_code * code)
1136 {
1137 stmtblock_t body;
1138 tree exit_label;
1139
1140 /* Create exit label so it is available for trans'ing the body code. */
1141 exit_label = gfc_build_label_decl (NULL_TREE);
1142 code->exit_label = exit_label;
1143
1144 /* Translate the actual code in code->block. */
1145 gfc_init_block (&body);
1146 gfc_add_expr_to_block (&body, gfc_trans_if_1 (code->block));
1147
1148 /* Add exit label. */
1149 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1150
1151 return gfc_finish_block (&body);
1152 }
1153
1154
1155 /* Translate an arithmetic IF expression.
1156
1157 IF (cond) label1, label2, label3 translates to
1158
1159 if (cond <= 0)
1160 {
1161 if (cond < 0)
1162 goto label1;
1163 else // cond == 0
1164 goto label2;
1165 }
1166 else // cond > 0
1167 goto label3;
1168
1169 An optimized version can be generated in case of equal labels.
1170 E.g., if label1 is equal to label2, we can translate it to
1171
1172 if (cond <= 0)
1173 goto label1;
1174 else
1175 goto label3;
1176 */
1177
1178 tree
1179 gfc_trans_arithmetic_if (gfc_code * code)
1180 {
1181 gfc_se se;
1182 tree tmp;
1183 tree branch1;
1184 tree branch2;
1185 tree zero;
1186
1187 /* Start a new block. */
1188 gfc_init_se (&se, NULL);
1189 gfc_start_block (&se.pre);
1190
1191 /* Pre-evaluate COND. */
1192 gfc_conv_expr_val (&se, code->expr1);
1193 se.expr = gfc_evaluate_now (se.expr, &se.pre);
1194
1195 /* Build something to compare with. */
1196 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
1197
1198 if (code->label1->value != code->label2->value)
1199 {
1200 /* If (cond < 0) take branch1 else take branch2.
1201 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
1202 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1203 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
1204
1205 if (code->label1->value != code->label3->value)
1206 tmp = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1207 se.expr, zero);
1208 else
1209 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1210 se.expr, zero);
1211
1212 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1213 tmp, branch1, branch2);
1214 }
1215 else
1216 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label1));
1217
1218 if (code->label1->value != code->label3->value
1219 && code->label2->value != code->label3->value)
1220 {
1221 /* if (cond <= 0) take branch1 else take branch2. */
1222 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
1223 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
1224 se.expr, zero);
1225 branch1 = fold_build3_loc (input_location, COND_EXPR, void_type_node,
1226 tmp, branch1, branch2);
1227 }
1228
1229 /* Append the COND_EXPR to the evaluation of COND, and return. */
1230 gfc_add_expr_to_block (&se.pre, branch1);
1231 return gfc_finish_block (&se.pre);
1232 }
1233
1234
1235 /* Translate a CRITICAL block. */
1236 tree
1237 gfc_trans_critical (gfc_code *code)
1238 {
1239 stmtblock_t block;
1240 tree tmp, token = NULL_TREE;
1241
1242 gfc_start_block (&block);
1243
1244 if (flag_coarray == GFC_FCOARRAY_LIB)
1245 {
1246 token = gfc_get_symbol_decl (code->resolved_sym);
1247 token = GFC_TYPE_ARRAY_CAF_TOKEN (TREE_TYPE (token));
1248 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_lock, 7,
1249 token, integer_zero_node, integer_one_node,
1250 null_pointer_node, null_pointer_node,
1251 null_pointer_node, integer_zero_node);
1252 gfc_add_expr_to_block (&block, tmp);
1253 }
1254
1255 tmp = gfc_trans_code (code->block->next);
1256 gfc_add_expr_to_block (&block, tmp);
1257
1258 if (flag_coarray == GFC_FCOARRAY_LIB)
1259 {
1260 tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_unlock, 6,
1261 token, integer_zero_node, integer_one_node,
1262 null_pointer_node, null_pointer_node,
1263 integer_zero_node);
1264 gfc_add_expr_to_block (&block, tmp);
1265 }
1266
1267
1268 return gfc_finish_block (&block);
1269 }
1270
1271
1272 /* Return true, when the class has a _len component. */
1273
1274 static bool
1275 class_has_len_component (gfc_symbol *sym)
1276 {
1277 gfc_component *comp = sym->ts.u.derived->components;
1278 while (comp)
1279 {
1280 if (strcmp (comp->name, "_len") == 0)
1281 return true;
1282 comp = comp->next;
1283 }
1284 return false;
1285 }
1286
1287
1288 /* Do proper initialization for ASSOCIATE names. */
1289
1290 static void
1291 trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
1292 {
1293 gfc_expr *e;
1294 tree tmp;
1295 bool class_target;
1296 bool unlimited;
1297 tree desc;
1298 tree offset;
1299 tree dim;
1300 int n;
1301 tree charlen;
1302 bool need_len_assign;
1303
1304 gcc_assert (sym->assoc);
1305 e = sym->assoc->target;
1306
1307 class_target = (e->expr_type == EXPR_VARIABLE)
1308 && (gfc_is_class_scalar_expr (e)
1309 || gfc_is_class_array_ref (e, NULL));
1310
1311 unlimited = UNLIMITED_POLY (e);
1312
1313 /* Assignments to the string length need to be generated, when
1314 ( sym is a char array or
1315 sym has a _len component)
1316 and the associated expression is unlimited polymorphic, which is
1317 not (yet) correctly in 'unlimited', because for an already associated
1318 BT_DERIVED the u-poly flag is not set, i.e.,
1319 __tmp_CHARACTER_0_1 => w => arg
1320 ^ generated temp ^ from code, the w does not have the u-poly
1321 flag set, where UNLIMITED_POLY(e) expects it. */
1322 need_len_assign = ((unlimited || (e->ts.type == BT_DERIVED
1323 && e->ts.u.derived->attr.unlimited_polymorphic))
1324 && (sym->ts.type == BT_CHARACTER
1325 || ((sym->ts.type == BT_CLASS || sym->ts.type == BT_DERIVED)
1326 && class_has_len_component (sym))));
1327 /* Do a `pointer assignment' with updated descriptor (or assign descriptor
1328 to array temporary) for arrays with either unknown shape or if associating
1329 to a variable. */
1330 if (sym->attr.dimension && !class_target
1331 && (sym->as->type == AS_DEFERRED || sym->assoc->variable))
1332 {
1333 gfc_se se;
1334 tree desc;
1335 bool cst_array_ctor;
1336
1337 desc = sym->backend_decl;
1338 cst_array_ctor = e->expr_type == EXPR_ARRAY
1339 && gfc_constant_array_constructor_p (e->value.constructor);
1340
1341 /* If association is to an expression, evaluate it and create temporary.
1342 Otherwise, get descriptor of target for pointer assignment. */
1343 gfc_init_se (&se, NULL);
1344 if (sym->assoc->variable || cst_array_ctor)
1345 {
1346 se.direct_byref = 1;
1347 se.use_offset = 1;
1348 se.expr = desc;
1349 }
1350
1351 gfc_conv_expr_descriptor (&se, e);
1352
1353 /* If we didn't already do the pointer assignment, set associate-name
1354 descriptor to the one generated for the temporary. */
1355 if (!sym->assoc->variable && !cst_array_ctor)
1356 {
1357 int dim;
1358
1359 gfc_add_modify (&se.pre, desc, se.expr);
1360
1361 /* The generated descriptor has lower bound zero (as array
1362 temporary), shift bounds so we get lower bounds of 1. */
1363 for (dim = 0; dim < e->rank; ++dim)
1364 gfc_conv_shift_descriptor_lbound (&se.pre, desc,
1365 dim, gfc_index_one_node);
1366 }
1367
1368 /* If this is a subreference array pointer associate name use the
1369 associate variable element size for the value of 'span'. */
1370 if (sym->attr.subref_array_pointer)
1371 {
1372 gcc_assert (e->expr_type == EXPR_VARIABLE);
1373 tmp = e->symtree->n.sym->backend_decl;
1374 tmp = gfc_get_element_type (TREE_TYPE (tmp));
1375 tmp = fold_convert (gfc_array_index_type, size_in_bytes (tmp));
1376 gfc_add_modify (&se.pre, GFC_DECL_SPAN(desc), tmp);
1377 }
1378
1379 /* Done, register stuff as init / cleanup code. */
1380 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1381 gfc_finish_block (&se.post));
1382 }
1383
1384 /* Temporaries, arising from TYPE IS, just need the descriptor of class
1385 arrays to be assigned directly. */
1386 else if (class_target && sym->attr.dimension
1387 && (sym->ts.type == BT_DERIVED || unlimited))
1388 {
1389 gfc_se se;
1390
1391 gfc_init_se (&se, NULL);
1392 se.descriptor_only = 1;
1393 /* In a select type the (temporary) associate variable shall point to
1394 a standard fortran array (lower bound == 1), but conv_expr ()
1395 just maps to the input array in the class object, whose lbound may
1396 be arbitrary. conv_expr_descriptor solves this by inserting a
1397 temporary array descriptor. */
1398 gfc_conv_expr_descriptor (&se, e);
1399
1400 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr))
1401 || GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)));
1402 gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (sym->backend_decl)));
1403
1404 if (GFC_ARRAY_TYPE_P (TREE_TYPE (se.expr)))
1405 {
1406 if (INDIRECT_REF_P (se.expr))
1407 tmp = TREE_OPERAND (se.expr, 0);
1408 else
1409 tmp = se.expr;
1410
1411 gfc_add_modify (&se.pre, sym->backend_decl,
1412 gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR (tmp)));
1413 }
1414 else
1415 gfc_add_modify (&se.pre, sym->backend_decl, se.expr);
1416
1417 if (unlimited)
1418 {
1419 /* Recover the dtype, which has been overwritten by the
1420 assignment from an unlimited polymorphic object. */
1421 tmp = gfc_conv_descriptor_dtype (sym->backend_decl);
1422 gfc_add_modify (&se.pre, tmp,
1423 gfc_get_dtype (TREE_TYPE (sym->backend_decl)));
1424 }
1425
1426 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1427 gfc_finish_block (&se.post));
1428 }
1429
1430 /* Do a scalar pointer assignment; this is for scalar variable targets. */
1431 else if (gfc_is_associate_pointer (sym))
1432 {
1433 gfc_se se;
1434
1435 gcc_assert (!sym->attr.dimension);
1436
1437 gfc_init_se (&se, NULL);
1438
1439 /* Class associate-names come this way because they are
1440 unconditionally associate pointers and the symbol is scalar. */
1441 if (sym->ts.type == BT_CLASS && CLASS_DATA (sym)->attr.dimension)
1442 {
1443 tree target_expr;
1444 /* For a class array we need a descriptor for the selector. */
1445 gfc_conv_expr_descriptor (&se, e);
1446 /* Needed to get/set the _len component below. */
1447 target_expr = se.expr;
1448
1449 /* Obtain a temporary class container for the result. */
1450 gfc_conv_class_to_class (&se, e, sym->ts, false, true, false, false);
1451 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1452
1453 /* Set the offset. */
1454 desc = gfc_class_data_get (se.expr);
1455 offset = gfc_index_zero_node;
1456 for (n = 0; n < e->rank; n++)
1457 {
1458 dim = gfc_rank_cst[n];
1459 tmp = fold_build2_loc (input_location, MULT_EXPR,
1460 gfc_array_index_type,
1461 gfc_conv_descriptor_stride_get (desc, dim),
1462 gfc_conv_descriptor_lbound_get (desc, dim));
1463 offset = fold_build2_loc (input_location, MINUS_EXPR,
1464 gfc_array_index_type,
1465 offset, tmp);
1466 }
1467 if (need_len_assign)
1468 {
1469 if (e->symtree
1470 && DECL_LANG_SPECIFIC (e->symtree->n.sym->backend_decl)
1471 && GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl))
1472 /* Use the original class descriptor stored in the saved
1473 descriptor to get the target_expr. */
1474 target_expr =
1475 GFC_DECL_SAVED_DESCRIPTOR (e->symtree->n.sym->backend_decl);
1476 else
1477 /* Strip the _data component from the target_expr. */
1478 target_expr = TREE_OPERAND (target_expr, 0);
1479 /* Add a reference to the _len comp to the target expr. */
1480 tmp = gfc_class_len_get (target_expr);
1481 /* Get the component-ref for the temp structure's _len comp. */
1482 charlen = gfc_class_len_get (se.expr);
1483 /* Add the assign to the beginning of the the block... */
1484 gfc_add_modify (&se.pre, charlen,
1485 fold_convert (TREE_TYPE (charlen), tmp));
1486 /* and the oposite way at the end of the block, to hand changes
1487 on the string length back. */
1488 gfc_add_modify (&se.post, tmp,
1489 fold_convert (TREE_TYPE (tmp), charlen));
1490 /* Length assignment done, prevent adding it again below. */
1491 need_len_assign = false;
1492 }
1493 gfc_conv_descriptor_offset_set (&se.pre, desc, offset);
1494 }
1495 else if (sym->ts.type == BT_CLASS && e->ts.type == BT_CLASS
1496 && CLASS_DATA (e)->attr.dimension)
1497 {
1498 /* This is bound to be a class array element. */
1499 gfc_conv_expr_reference (&se, e);
1500 /* Get the _vptr component of the class object. */
1501 tmp = gfc_get_vptr_from_expr (se.expr);
1502 /* Obtain a temporary class container for the result. */
1503 gfc_conv_derived_to_class (&se, e, sym->ts, tmp, false, false);
1504 se.expr = build_fold_indirect_ref_loc (input_location, se.expr);
1505 }
1506 else
1507 {
1508 /* For BT_CLASS and BT_DERIVED, this boils down to a pointer assign,
1509 which has the string length included. For CHARACTERS it is still
1510 needed and will be done at the end of this routine. */
1511 gfc_conv_expr (&se, e);
1512 need_len_assign = need_len_assign && sym->ts.type == BT_CHARACTER;
1513 }
1514
1515 tmp = TREE_TYPE (sym->backend_decl);
1516 tmp = gfc_build_addr_expr (tmp, se.expr);
1517 gfc_add_modify (&se.pre, sym->backend_decl, tmp);
1518
1519 gfc_add_init_cleanup (block, gfc_finish_block( &se.pre),
1520 gfc_finish_block (&se.post));
1521 }
1522
1523 /* Do a simple assignment. This is for scalar expressions, where we
1524 can simply use expression assignment. */
1525 else
1526 {
1527 gfc_expr *lhs;
1528
1529 lhs = gfc_lval_expr_from_sym (sym);
1530 tmp = gfc_trans_assignment (lhs, e, false, true);
1531 gfc_add_init_cleanup (block, tmp, NULL_TREE);
1532 }
1533
1534 /* Set the stringlength, when needed. */
1535 if (need_len_assign)
1536 {
1537 gfc_se se;
1538 gfc_init_se (&se, NULL);
1539 if (e->symtree->n.sym->ts.type == BT_CHARACTER)
1540 {
1541 /* What about deferred strings? */
1542 gcc_assert (!e->symtree->n.sym->ts.deferred);
1543 tmp = e->symtree->n.sym->ts.u.cl->backend_decl;
1544 }
1545 else
1546 tmp = gfc_class_len_get (gfc_get_symbol_decl (e->symtree->n.sym));
1547 gfc_get_symbol_decl (sym);
1548 charlen = sym->ts.type == BT_CHARACTER ? sym->ts.u.cl->backend_decl
1549 : gfc_class_len_get (sym->backend_decl);
1550 /* Prevent adding a noop len= len. */
1551 if (tmp != charlen)
1552 {
1553 gfc_add_modify (&se.pre, charlen,
1554 fold_convert (TREE_TYPE (charlen), tmp));
1555 gfc_add_init_cleanup (block, gfc_finish_block (&se.pre),
1556 gfc_finish_block (&se.post));
1557 }
1558 }
1559 }
1560
1561
1562 /* Translate a BLOCK construct. This is basically what we would do for a
1563 procedure body. */
1564
1565 tree
1566 gfc_trans_block_construct (gfc_code* code)
1567 {
1568 gfc_namespace* ns;
1569 gfc_symbol* sym;
1570 gfc_wrapped_block block;
1571 tree exit_label;
1572 stmtblock_t body;
1573 gfc_association_list *ass;
1574
1575 ns = code->ext.block.ns;
1576 gcc_assert (ns);
1577 sym = ns->proc_name;
1578 gcc_assert (sym);
1579
1580 /* Process local variables. */
1581 gcc_assert (!sym->tlink);
1582 sym->tlink = sym;
1583 gfc_process_block_locals (ns);
1584
1585 /* Generate code including exit-label. */
1586 gfc_init_block (&body);
1587 exit_label = gfc_build_label_decl (NULL_TREE);
1588 code->exit_label = exit_label;
1589
1590 /* Generate !$ACC DECLARE directive. */
1591 if (ns->oacc_declare_clauses)
1592 {
1593 tree tmp = gfc_trans_oacc_declare (&body, ns);
1594 gfc_add_expr_to_block (&body, tmp);
1595 }
1596
1597 gfc_add_expr_to_block (&body, gfc_trans_code (ns->code));
1598 gfc_add_expr_to_block (&body, build1_v (LABEL_EXPR, exit_label));
1599
1600 /* Finish everything. */
1601 gfc_start_wrapped_block (&block, gfc_finish_block (&body));
1602 gfc_trans_deferred_vars (sym, &block);
1603 for (ass = code->ext.block.assoc; ass; ass = ass->next)
1604 trans_associate_var (ass->st->n.sym, &block);
1605
1606 return gfc_finish_wrapped_block (&block);
1607 }
1608
1609
1610 /* Translate the simple DO construct. This is where the loop variable has
1611 integer type and step +-1. We can't use this in the general case
1612 because integer overflow and floating point errors could give incorrect
1613 results.
1614 We translate a do loop from:
1615
1616 DO dovar = from, to, step
1617 body
1618 END DO
1619
1620 to:
1621
1622 [Evaluate loop bounds and step]
1623 dovar = from;
1624 if ((step > 0) ? (dovar <= to) : (dovar => to))
1625 {
1626 for (;;)
1627 {
1628 body;
1629 cycle_label:
1630 cond = (dovar == to);
1631 dovar += step;
1632 if (cond) goto end_label;
1633 }
1634 }
1635 end_label:
1636
1637 This helps the optimizers by avoiding the extra induction variable
1638 used in the general case. */
1639
1640 static tree
1641 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
1642 tree from, tree to, tree step, tree exit_cond)
1643 {
1644 stmtblock_t body;
1645 tree type;
1646 tree cond;
1647 tree tmp;
1648 tree saved_dovar = NULL;
1649 tree cycle_label;
1650 tree exit_label;
1651 location_t loc;
1652
1653 type = TREE_TYPE (dovar);
1654
1655 loc = code->ext.iterator->start->where.lb->location;
1656
1657 /* Initialize the DO variable: dovar = from. */
1658 gfc_add_modify_loc (loc, pblock, dovar,
1659 fold_convert (TREE_TYPE(dovar), from));
1660
1661 /* Save value for do-tinkering checking. */
1662 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1663 {
1664 saved_dovar = gfc_create_var (type, ".saved_dovar");
1665 gfc_add_modify_loc (loc, pblock, saved_dovar, dovar);
1666 }
1667
1668 /* Cycle and exit statements are implemented with gotos. */
1669 cycle_label = gfc_build_label_decl (NULL_TREE);
1670 exit_label = gfc_build_label_decl (NULL_TREE);
1671
1672 /* Put the labels where they can be found later. See gfc_trans_do(). */
1673 code->cycle_label = cycle_label;
1674 code->exit_label = exit_label;
1675
1676 /* Loop body. */
1677 gfc_start_block (&body);
1678
1679 /* Main loop body. */
1680 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1681 gfc_add_expr_to_block (&body, tmp);
1682
1683 /* Label for cycle statements (if needed). */
1684 if (TREE_USED (cycle_label))
1685 {
1686 tmp = build1_v (LABEL_EXPR, cycle_label);
1687 gfc_add_expr_to_block (&body, tmp);
1688 }
1689
1690 /* Check whether someone has modified the loop variable. */
1691 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1692 {
1693 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node,
1694 dovar, saved_dovar);
1695 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1696 "Loop variable has been modified");
1697 }
1698
1699 /* Exit the loop if there is an I/O result condition or error. */
1700 if (exit_cond)
1701 {
1702 tmp = build1_v (GOTO_EXPR, exit_label);
1703 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1704 exit_cond, tmp,
1705 build_empty_stmt (loc));
1706 gfc_add_expr_to_block (&body, tmp);
1707 }
1708
1709 /* Evaluate the loop condition. */
1710 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, dovar,
1711 to);
1712 cond = gfc_evaluate_now_loc (loc, cond, &body);
1713
1714 /* Increment the loop variable. */
1715 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1716 gfc_add_modify_loc (loc, &body, dovar, tmp);
1717
1718 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1719 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
1720
1721 /* The loop exit. */
1722 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
1723 TREE_USED (exit_label) = 1;
1724 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1725 cond, tmp, build_empty_stmt (loc));
1726 gfc_add_expr_to_block (&body, tmp);
1727
1728 /* Finish the loop body. */
1729 tmp = gfc_finish_block (&body);
1730 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
1731
1732 /* Only execute the loop if the number of iterations is positive. */
1733 if (tree_int_cst_sgn (step) > 0)
1734 cond = fold_build2_loc (loc, LE_EXPR, boolean_type_node, dovar,
1735 to);
1736 else
1737 cond = fold_build2_loc (loc, GE_EXPR, boolean_type_node, dovar,
1738 to);
1739 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, cond, tmp,
1740 build_empty_stmt (loc));
1741 gfc_add_expr_to_block (pblock, tmp);
1742
1743 /* Add the exit label. */
1744 tmp = build1_v (LABEL_EXPR, exit_label);
1745 gfc_add_expr_to_block (pblock, tmp);
1746
1747 return gfc_finish_block (pblock);
1748 }
1749
1750 /* Translate the DO construct. This obviously is one of the most
1751 important ones to get right with any compiler, but especially
1752 so for Fortran.
1753
1754 We special case some loop forms as described in gfc_trans_simple_do.
1755 For other cases we implement them with a separate loop count,
1756 as described in the standard.
1757
1758 We translate a do loop from:
1759
1760 DO dovar = from, to, step
1761 body
1762 END DO
1763
1764 to:
1765
1766 [evaluate loop bounds and step]
1767 empty = (step > 0 ? to < from : to > from);
1768 countm1 = (to - from) / step;
1769 dovar = from;
1770 if (empty) goto exit_label;
1771 for (;;)
1772 {
1773 body;
1774 cycle_label:
1775 dovar += step
1776 countm1t = countm1;
1777 countm1--;
1778 if (countm1t == 0) goto exit_label;
1779 }
1780 exit_label:
1781
1782 countm1 is an unsigned integer. It is equal to the loop count minus one,
1783 because the loop count itself can overflow. */
1784
1785 tree
1786 gfc_trans_do (gfc_code * code, tree exit_cond)
1787 {
1788 gfc_se se;
1789 tree dovar;
1790 tree saved_dovar = NULL;
1791 tree from;
1792 tree to;
1793 tree step;
1794 tree countm1;
1795 tree type;
1796 tree utype;
1797 tree cond;
1798 tree cycle_label;
1799 tree exit_label;
1800 tree tmp;
1801 stmtblock_t block;
1802 stmtblock_t body;
1803 location_t loc;
1804
1805 gfc_start_block (&block);
1806
1807 loc = code->ext.iterator->start->where.lb->location;
1808
1809 /* Evaluate all the expressions in the iterator. */
1810 gfc_init_se (&se, NULL);
1811 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
1812 gfc_add_block_to_block (&block, &se.pre);
1813 dovar = se.expr;
1814 type = TREE_TYPE (dovar);
1815
1816 gfc_init_se (&se, NULL);
1817 gfc_conv_expr_val (&se, code->ext.iterator->start);
1818 gfc_add_block_to_block (&block, &se.pre);
1819 from = gfc_evaluate_now (se.expr, &block);
1820
1821 gfc_init_se (&se, NULL);
1822 gfc_conv_expr_val (&se, code->ext.iterator->end);
1823 gfc_add_block_to_block (&block, &se.pre);
1824 to = gfc_evaluate_now (se.expr, &block);
1825
1826 gfc_init_se (&se, NULL);
1827 gfc_conv_expr_val (&se, code->ext.iterator->step);
1828 gfc_add_block_to_block (&block, &se.pre);
1829 step = gfc_evaluate_now (se.expr, &block);
1830
1831 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1832 {
1833 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, step,
1834 build_zero_cst (type));
1835 gfc_trans_runtime_check (true, false, tmp, &block, &code->loc,
1836 "DO step value is zero");
1837 }
1838
1839 /* Special case simple loops. */
1840 if (TREE_CODE (type) == INTEGER_TYPE
1841 && (integer_onep (step)
1842 || tree_int_cst_equal (step, integer_minus_one_node)))
1843 return gfc_trans_simple_do (code, &block, dovar, from, to, step, exit_cond);
1844
1845
1846 if (TREE_CODE (type) == INTEGER_TYPE)
1847 utype = unsigned_type_for (type);
1848 else
1849 utype = unsigned_type_for (gfc_array_index_type);
1850 countm1 = gfc_create_var (utype, "countm1");
1851
1852 /* Cycle and exit statements are implemented with gotos. */
1853 cycle_label = gfc_build_label_decl (NULL_TREE);
1854 exit_label = gfc_build_label_decl (NULL_TREE);
1855 TREE_USED (exit_label) = 1;
1856
1857 /* Put these labels where they can be found later. */
1858 code->cycle_label = cycle_label;
1859 code->exit_label = exit_label;
1860
1861 /* Initialize the DO variable: dovar = from. */
1862 gfc_add_modify (&block, dovar, from);
1863
1864 /* Save value for do-tinkering checking. */
1865 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1866 {
1867 saved_dovar = gfc_create_var (type, ".saved_dovar");
1868 gfc_add_modify_loc (loc, &block, saved_dovar, dovar);
1869 }
1870
1871 /* Initialize loop count and jump to exit label if the loop is empty.
1872 This code is executed before we enter the loop body. We generate:
1873 if (step > 0)
1874 {
1875 countm1 = (to - from) / step;
1876 if (to < from)
1877 goto exit_label;
1878 }
1879 else
1880 {
1881 countm1 = (from - to) / -step;
1882 if (to > from)
1883 goto exit_label;
1884 }
1885 */
1886
1887 if (TREE_CODE (type) == INTEGER_TYPE)
1888 {
1889 tree pos, neg, tou, fromu, stepu, tmp2;
1890
1891 /* The distance from FROM to TO cannot always be represented in a signed
1892 type, thus use unsigned arithmetic, also to avoid any undefined
1893 overflow issues. */
1894 tou = fold_convert (utype, to);
1895 fromu = fold_convert (utype, from);
1896 stepu = fold_convert (utype, step);
1897
1898 /* For a positive step, when to < from, exit, otherwise compute
1899 countm1 = ((unsigned)to - (unsigned)from) / (unsigned)step */
1900 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, to, from);
1901 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
1902 fold_build2_loc (loc, MINUS_EXPR, utype,
1903 tou, fromu),
1904 stepu);
1905 pos = build2 (COMPOUND_EXPR, void_type_node,
1906 fold_build2 (MODIFY_EXPR, void_type_node,
1907 countm1, tmp2),
1908 build3_loc (loc, COND_EXPR, void_type_node, tmp,
1909 build1_loc (loc, GOTO_EXPR, void_type_node,
1910 exit_label), NULL_TREE));
1911
1912 /* For a negative step, when to > from, exit, otherwise compute
1913 countm1 = ((unsigned)from - (unsigned)to) / -(unsigned)step */
1914 tmp = fold_build2_loc (loc, GT_EXPR, boolean_type_node, to, from);
1915 tmp2 = fold_build2_loc (loc, TRUNC_DIV_EXPR, utype,
1916 fold_build2_loc (loc, MINUS_EXPR, utype,
1917 fromu, tou),
1918 fold_build1_loc (loc, NEGATE_EXPR, utype, stepu));
1919 neg = build2 (COMPOUND_EXPR, void_type_node,
1920 fold_build2 (MODIFY_EXPR, void_type_node,
1921 countm1, tmp2),
1922 build3_loc (loc, COND_EXPR, void_type_node, tmp,
1923 build1_loc (loc, GOTO_EXPR, void_type_node,
1924 exit_label), NULL_TREE));
1925
1926 tmp = fold_build2_loc (loc, LT_EXPR, boolean_type_node, step,
1927 build_int_cst (TREE_TYPE (step), 0));
1928 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp, neg, pos);
1929
1930 gfc_add_expr_to_block (&block, tmp);
1931 }
1932 else
1933 {
1934 tree pos_step;
1935
1936 /* TODO: We could use the same width as the real type.
1937 This would probably cause more problems that it solves
1938 when we implement "long double" types. */
1939
1940 tmp = fold_build2_loc (loc, MINUS_EXPR, type, to, from);
1941 tmp = fold_build2_loc (loc, RDIV_EXPR, type, tmp, step);
1942 tmp = fold_build1_loc (loc, FIX_TRUNC_EXPR, utype, tmp);
1943 gfc_add_modify (&block, countm1, tmp);
1944
1945 /* We need a special check for empty loops:
1946 empty = (step > 0 ? to < from : to > from); */
1947 pos_step = fold_build2_loc (loc, GT_EXPR, boolean_type_node, step,
1948 build_zero_cst (type));
1949 tmp = fold_build3_loc (loc, COND_EXPR, boolean_type_node, pos_step,
1950 fold_build2_loc (loc, LT_EXPR,
1951 boolean_type_node, to, from),
1952 fold_build2_loc (loc, GT_EXPR,
1953 boolean_type_node, to, from));
1954 /* If the loop is empty, go directly to the exit label. */
1955 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node, tmp,
1956 build1_v (GOTO_EXPR, exit_label),
1957 build_empty_stmt (input_location));
1958 gfc_add_expr_to_block (&block, tmp);
1959 }
1960
1961 /* Loop body. */
1962 gfc_start_block (&body);
1963
1964 /* Main loop body. */
1965 tmp = gfc_trans_code_cond (code->block->next, exit_cond);
1966 gfc_add_expr_to_block (&body, tmp);
1967
1968 /* Label for cycle statements (if needed). */
1969 if (TREE_USED (cycle_label))
1970 {
1971 tmp = build1_v (LABEL_EXPR, cycle_label);
1972 gfc_add_expr_to_block (&body, tmp);
1973 }
1974
1975 /* Check whether someone has modified the loop variable. */
1976 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1977 {
1978 tmp = fold_build2_loc (loc, NE_EXPR, boolean_type_node, dovar,
1979 saved_dovar);
1980 gfc_trans_runtime_check (true, false, tmp, &body, &code->loc,
1981 "Loop variable has been modified");
1982 }
1983
1984 /* Exit the loop if there is an I/O result condition or error. */
1985 if (exit_cond)
1986 {
1987 tmp = build1_v (GOTO_EXPR, exit_label);
1988 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
1989 exit_cond, tmp,
1990 build_empty_stmt (input_location));
1991 gfc_add_expr_to_block (&body, tmp);
1992 }
1993
1994 /* Increment the loop variable. */
1995 tmp = fold_build2_loc (loc, PLUS_EXPR, type, dovar, step);
1996 gfc_add_modify_loc (loc, &body, dovar, tmp);
1997
1998 if (gfc_option.rtcheck & GFC_RTCHECK_DO)
1999 gfc_add_modify_loc (loc, &body, saved_dovar, dovar);
2000
2001 /* Initialize countm1t. */
2002 tree countm1t = gfc_create_var (utype, "countm1t");
2003 gfc_add_modify_loc (loc, &body, countm1t, countm1);
2004
2005 /* Decrement the loop count. */
2006 tmp = fold_build2_loc (loc, MINUS_EXPR, utype, countm1,
2007 build_int_cst (utype, 1));
2008 gfc_add_modify_loc (loc, &body, countm1, tmp);
2009
2010 /* End with the loop condition. Loop until countm1t == 0. */
2011 cond = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, countm1t,
2012 build_int_cst (utype, 0));
2013 tmp = fold_build1_loc (loc, GOTO_EXPR, void_type_node, exit_label);
2014 tmp = fold_build3_loc (loc, COND_EXPR, void_type_node,
2015 cond, tmp, build_empty_stmt (loc));
2016 gfc_add_expr_to_block (&body, tmp);
2017
2018 /* End of loop body. */
2019 tmp = gfc_finish_block (&body);
2020
2021 /* The for loop itself. */
2022 tmp = fold_build1_loc (loc, LOOP_EXPR, void_type_node, tmp);
2023 gfc_add_expr_to_block (&block, tmp);
2024
2025 /* Add the exit label. */
2026 tmp = build1_v (LABEL_EXPR, exit_label);
2027 gfc_add_expr_to_block (&block, tmp);
2028
2029 return gfc_finish_block (&block);
2030 }
2031
2032
2033 /* Translate the DO WHILE construct.
2034
2035 We translate
2036
2037 DO WHILE (cond)
2038 body
2039 END DO
2040
2041 to:
2042
2043 for ( ; ; )
2044 {
2045 pre_cond;
2046 if (! cond) goto exit_label;
2047 body;
2048 cycle_label:
2049 }
2050 exit_label:
2051
2052 Because the evaluation of the exit condition `cond' may have side
2053 effects, we can't do much for empty loop bodies. The backend optimizers
2054 should be smart enough to eliminate any dead loops. */
2055
2056 tree
2057 gfc_trans_do_while (gfc_code * code)
2058 {
2059 gfc_se cond;
2060 tree tmp;
2061 tree cycle_label;
2062 tree exit_label;
2063 stmtblock_t block;
2064
2065 /* Everything we build here is part of the loop body. */
2066 gfc_start_block (&block);
2067
2068 /* Cycle and exit statements are implemented with gotos. */
2069 cycle_label = gfc_build_label_decl (NULL_TREE);
2070 exit_label = gfc_build_label_decl (NULL_TREE);
2071
2072 /* Put the labels where they can be found later. See gfc_trans_do(). */
2073 code->cycle_label = cycle_label;
2074 code->exit_label = exit_label;
2075
2076 /* Create a GIMPLE version of the exit condition. */
2077 gfc_init_se (&cond, NULL);
2078 gfc_conv_expr_val (&cond, code->expr1);
2079 gfc_add_block_to_block (&block, &cond.pre);
2080 cond.expr = fold_build1_loc (code->expr1->where.lb->location,
2081 TRUTH_NOT_EXPR, TREE_TYPE (cond.expr), cond.expr);
2082
2083 /* Build "IF (! cond) GOTO exit_label". */
2084 tmp = build1_v (GOTO_EXPR, exit_label);
2085 TREE_USED (exit_label) = 1;
2086 tmp = fold_build3_loc (code->expr1->where.lb->location, COND_EXPR,
2087 void_type_node, cond.expr, tmp,
2088 build_empty_stmt (code->expr1->where.lb->location));
2089 gfc_add_expr_to_block (&block, tmp);
2090
2091 /* The main body of the loop. */
2092 tmp = gfc_trans_code (code->block->next);
2093 gfc_add_expr_to_block (&block, tmp);
2094
2095 /* Label for cycle statements (if needed). */
2096 if (TREE_USED (cycle_label))
2097 {
2098 tmp = build1_v (LABEL_EXPR, cycle_label);
2099 gfc_add_expr_to_block (&block, tmp);
2100 }
2101
2102 /* End of loop body. */
2103 tmp = gfc_finish_block (&block);
2104
2105 gfc_init_block (&block);
2106 /* Build the loop. */
2107 tmp = fold_build1_loc (code->expr1->where.lb->location, LOOP_EXPR,
2108 void_type_node, tmp);
2109 gfc_add_expr_to_block (&block, tmp);
2110
2111 /* Add the exit label. */
2112 tmp = build1_v (LABEL_EXPR, exit_label);
2113 gfc_add_expr_to_block (&block, tmp);
2114
2115 return gfc_finish_block (&block);
2116 }
2117
2118
2119 /* Translate the SELECT CASE construct for INTEGER case expressions,
2120 without killing all potential optimizations. The problem is that
2121 Fortran allows unbounded cases, but the back-end does not, so we
2122 need to intercept those before we enter the equivalent SWITCH_EXPR
2123 we can build.
2124
2125 For example, we translate this,
2126
2127 SELECT CASE (expr)
2128 CASE (:100,101,105:115)
2129 block_1
2130 CASE (190:199,200:)
2131 block_2
2132 CASE (300)
2133 block_3
2134 CASE DEFAULT
2135 block_4
2136 END SELECT
2137
2138 to the GENERIC equivalent,
2139
2140 switch (expr)
2141 {
2142 case (minimum value for typeof(expr) ... 100:
2143 case 101:
2144 case 105 ... 114:
2145 block1:
2146 goto end_label;
2147
2148 case 200 ... (maximum value for typeof(expr):
2149 case 190 ... 199:
2150 block2;
2151 goto end_label;
2152
2153 case 300:
2154 block_3;
2155 goto end_label;
2156
2157 default:
2158 block_4;
2159 goto end_label;
2160 }
2161
2162 end_label: */
2163
2164 static tree
2165 gfc_trans_integer_select (gfc_code * code)
2166 {
2167 gfc_code *c;
2168 gfc_case *cp;
2169 tree end_label;
2170 tree tmp;
2171 gfc_se se;
2172 stmtblock_t block;
2173 stmtblock_t body;
2174
2175 gfc_start_block (&block);
2176
2177 /* Calculate the switch expression. */
2178 gfc_init_se (&se, NULL);
2179 gfc_conv_expr_val (&se, code->expr1);
2180 gfc_add_block_to_block (&block, &se.pre);
2181
2182 end_label = gfc_build_label_decl (NULL_TREE);
2183
2184 gfc_init_block (&body);
2185
2186 for (c = code->block; c; c = c->block)
2187 {
2188 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2189 {
2190 tree low, high;
2191 tree label;
2192
2193 /* Assume it's the default case. */
2194 low = high = NULL_TREE;
2195
2196 if (cp->low)
2197 {
2198 low = gfc_conv_mpz_to_tree (cp->low->value.integer,
2199 cp->low->ts.kind);
2200
2201 /* If there's only a lower bound, set the high bound to the
2202 maximum value of the case expression. */
2203 if (!cp->high)
2204 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
2205 }
2206
2207 if (cp->high)
2208 {
2209 /* Three cases are possible here:
2210
2211 1) There is no lower bound, e.g. CASE (:N).
2212 2) There is a lower bound .NE. high bound, that is
2213 a case range, e.g. CASE (N:M) where M>N (we make
2214 sure that M>N during type resolution).
2215 3) There is a lower bound, and it has the same value
2216 as the high bound, e.g. CASE (N:N). This is our
2217 internal representation of CASE(N).
2218
2219 In the first and second case, we need to set a value for
2220 high. In the third case, we don't because the GCC middle
2221 end represents a single case value by just letting high be
2222 a NULL_TREE. We can't do that because we need to be able
2223 to represent unbounded cases. */
2224
2225 if (!cp->low
2226 || (cp->low
2227 && mpz_cmp (cp->low->value.integer,
2228 cp->high->value.integer) != 0))
2229 high = gfc_conv_mpz_to_tree (cp->high->value.integer,
2230 cp->high->ts.kind);
2231
2232 /* Unbounded case. */
2233 if (!cp->low)
2234 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
2235 }
2236
2237 /* Build a label. */
2238 label = gfc_build_label_decl (NULL_TREE);
2239
2240 /* Add this case label.
2241 Add parameter 'label', make it match GCC backend. */
2242 tmp = build_case_label (low, high, label);
2243 gfc_add_expr_to_block (&body, tmp);
2244 }
2245
2246 /* Add the statements for this case. */
2247 tmp = gfc_trans_code (c->next);
2248 gfc_add_expr_to_block (&body, tmp);
2249
2250 /* Break to the end of the construct. */
2251 tmp = build1_v (GOTO_EXPR, end_label);
2252 gfc_add_expr_to_block (&body, tmp);
2253 }
2254
2255 tmp = gfc_finish_block (&body);
2256 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2257 se.expr, tmp, NULL_TREE);
2258 gfc_add_expr_to_block (&block, tmp);
2259
2260 tmp = build1_v (LABEL_EXPR, end_label);
2261 gfc_add_expr_to_block (&block, tmp);
2262
2263 return gfc_finish_block (&block);
2264 }
2265
2266
2267 /* Translate the SELECT CASE construct for LOGICAL case expressions.
2268
2269 There are only two cases possible here, even though the standard
2270 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
2271 .FALSE., and DEFAULT.
2272
2273 We never generate more than two blocks here. Instead, we always
2274 try to eliminate the DEFAULT case. This way, we can translate this
2275 kind of SELECT construct to a simple
2276
2277 if {} else {};
2278
2279 expression in GENERIC. */
2280
2281 static tree
2282 gfc_trans_logical_select (gfc_code * code)
2283 {
2284 gfc_code *c;
2285 gfc_code *t, *f, *d;
2286 gfc_case *cp;
2287 gfc_se se;
2288 stmtblock_t block;
2289
2290 /* Assume we don't have any cases at all. */
2291 t = f = d = NULL;
2292
2293 /* Now see which ones we actually do have. We can have at most two
2294 cases in a single case list: one for .TRUE. and one for .FALSE.
2295 The default case is always separate. If the cases for .TRUE. and
2296 .FALSE. are in the same case list, the block for that case list
2297 always executed, and we don't generate code a COND_EXPR. */
2298 for (c = code->block; c; c = c->block)
2299 {
2300 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2301 {
2302 if (cp->low)
2303 {
2304 if (cp->low->value.logical == 0) /* .FALSE. */
2305 f = c;
2306 else /* if (cp->value.logical != 0), thus .TRUE. */
2307 t = c;
2308 }
2309 else
2310 d = c;
2311 }
2312 }
2313
2314 /* Start a new block. */
2315 gfc_start_block (&block);
2316
2317 /* Calculate the switch expression. We always need to do this
2318 because it may have side effects. */
2319 gfc_init_se (&se, NULL);
2320 gfc_conv_expr_val (&se, code->expr1);
2321 gfc_add_block_to_block (&block, &se.pre);
2322
2323 if (t == f && t != NULL)
2324 {
2325 /* Cases for .TRUE. and .FALSE. are in the same block. Just
2326 translate the code for these cases, append it to the current
2327 block. */
2328 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
2329 }
2330 else
2331 {
2332 tree true_tree, false_tree, stmt;
2333
2334 true_tree = build_empty_stmt (input_location);
2335 false_tree = build_empty_stmt (input_location);
2336
2337 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
2338 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
2339 make the missing case the default case. */
2340 if (t != NULL && f != NULL)
2341 d = NULL;
2342 else if (d != NULL)
2343 {
2344 if (t == NULL)
2345 t = d;
2346 else
2347 f = d;
2348 }
2349
2350 /* Translate the code for each of these blocks, and append it to
2351 the current block. */
2352 if (t != NULL)
2353 true_tree = gfc_trans_code (t->next);
2354
2355 if (f != NULL)
2356 false_tree = gfc_trans_code (f->next);
2357
2358 stmt = fold_build3_loc (input_location, COND_EXPR, void_type_node,
2359 se.expr, true_tree, false_tree);
2360 gfc_add_expr_to_block (&block, stmt);
2361 }
2362
2363 return gfc_finish_block (&block);
2364 }
2365
2366
2367 /* The jump table types are stored in static variables to avoid
2368 constructing them from scratch every single time. */
2369 static GTY(()) tree select_struct[2];
2370
2371 /* Translate the SELECT CASE construct for CHARACTER case expressions.
2372 Instead of generating compares and jumps, it is far simpler to
2373 generate a data structure describing the cases in order and call a
2374 library subroutine that locates the right case.
2375 This is particularly true because this is the only case where we
2376 might have to dispose of a temporary.
2377 The library subroutine returns a pointer to jump to or NULL if no
2378 branches are to be taken. */
2379
2380 static tree
2381 gfc_trans_character_select (gfc_code *code)
2382 {
2383 tree init, end_label, tmp, type, case_num, label, fndecl;
2384 stmtblock_t block, body;
2385 gfc_case *cp, *d;
2386 gfc_code *c;
2387 gfc_se se, expr1se;
2388 int n, k;
2389 vec<constructor_elt, va_gc> *inits = NULL;
2390
2391 tree pchartype = gfc_get_pchar_type (code->expr1->ts.kind);
2392
2393 /* The jump table types are stored in static variables to avoid
2394 constructing them from scratch every single time. */
2395 static tree ss_string1[2], ss_string1_len[2];
2396 static tree ss_string2[2], ss_string2_len[2];
2397 static tree ss_target[2];
2398
2399 cp = code->block->ext.block.case_list;
2400 while (cp->left != NULL)
2401 cp = cp->left;
2402
2403 /* Generate the body */
2404 gfc_start_block (&block);
2405 gfc_init_se (&expr1se, NULL);
2406 gfc_conv_expr_reference (&expr1se, code->expr1);
2407
2408 gfc_add_block_to_block (&block, &expr1se.pre);
2409
2410 end_label = gfc_build_label_decl (NULL_TREE);
2411
2412 gfc_init_block (&body);
2413
2414 /* Attempt to optimize length 1 selects. */
2415 if (integer_onep (expr1se.string_length))
2416 {
2417 for (d = cp; d; d = d->right)
2418 {
2419 int i;
2420 if (d->low)
2421 {
2422 gcc_assert (d->low->expr_type == EXPR_CONSTANT
2423 && d->low->ts.type == BT_CHARACTER);
2424 if (d->low->value.character.length > 1)
2425 {
2426 for (i = 1; i < d->low->value.character.length; i++)
2427 if (d->low->value.character.string[i] != ' ')
2428 break;
2429 if (i != d->low->value.character.length)
2430 {
2431 if (optimize && d->high && i == 1)
2432 {
2433 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2434 && d->high->ts.type == BT_CHARACTER);
2435 if (d->high->value.character.length > 1
2436 && (d->low->value.character.string[0]
2437 == d->high->value.character.string[0])
2438 && d->high->value.character.string[1] != ' '
2439 && ((d->low->value.character.string[1] < ' ')
2440 == (d->high->value.character.string[1]
2441 < ' ')))
2442 continue;
2443 }
2444 break;
2445 }
2446 }
2447 }
2448 if (d->high)
2449 {
2450 gcc_assert (d->high->expr_type == EXPR_CONSTANT
2451 && d->high->ts.type == BT_CHARACTER);
2452 if (d->high->value.character.length > 1)
2453 {
2454 for (i = 1; i < d->high->value.character.length; i++)
2455 if (d->high->value.character.string[i] != ' ')
2456 break;
2457 if (i != d->high->value.character.length)
2458 break;
2459 }
2460 }
2461 }
2462 if (d == NULL)
2463 {
2464 tree ctype = gfc_get_char_type (code->expr1->ts.kind);
2465
2466 for (c = code->block; c; c = c->block)
2467 {
2468 for (cp = c->ext.block.case_list; cp; cp = cp->next)
2469 {
2470 tree low, high;
2471 tree label;
2472 gfc_char_t r;
2473
2474 /* Assume it's the default case. */
2475 low = high = NULL_TREE;
2476
2477 if (cp->low)
2478 {
2479 /* CASE ('ab') or CASE ('ab':'az') will never match
2480 any length 1 character. */
2481 if (cp->low->value.character.length > 1
2482 && cp->low->value.character.string[1] != ' ')
2483 continue;
2484
2485 if (cp->low->value.character.length > 0)
2486 r = cp->low->value.character.string[0];
2487 else
2488 r = ' ';
2489 low = build_int_cst (ctype, r);
2490
2491 /* If there's only a lower bound, set the high bound
2492 to the maximum value of the case expression. */
2493 if (!cp->high)
2494 high = TYPE_MAX_VALUE (ctype);
2495 }
2496
2497 if (cp->high)
2498 {
2499 if (!cp->low
2500 || (cp->low->value.character.string[0]
2501 != cp->high->value.character.string[0]))
2502 {
2503 if (cp->high->value.character.length > 0)
2504 r = cp->high->value.character.string[0];
2505 else
2506 r = ' ';
2507 high = build_int_cst (ctype, r);
2508 }
2509
2510 /* Unbounded case. */
2511 if (!cp->low)
2512 low = TYPE_MIN_VALUE (ctype);
2513 }
2514
2515 /* Build a label. */
2516 label = gfc_build_label_decl (NULL_TREE);
2517
2518 /* Add this case label.
2519 Add parameter 'label', make it match GCC backend. */
2520 tmp = build_case_label (low, high, label);
2521 gfc_add_expr_to_block (&body, tmp);
2522 }
2523
2524 /* Add the statements for this case. */
2525 tmp = gfc_trans_code (c->next);
2526 gfc_add_expr_to_block (&body, tmp);
2527
2528 /* Break to the end of the construct. */
2529 tmp = build1_v (GOTO_EXPR, end_label);
2530 gfc_add_expr_to_block (&body, tmp);
2531 }
2532
2533 tmp = gfc_string_to_single_character (expr1se.string_length,
2534 expr1se.expr,
2535 code->expr1->ts.kind);
2536 case_num = gfc_create_var (ctype, "case_num");
2537 gfc_add_modify (&block, case_num, tmp);
2538
2539 gfc_add_block_to_block (&block, &expr1se.post);
2540
2541 tmp = gfc_finish_block (&body);
2542 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2543 case_num, tmp, NULL_TREE);
2544 gfc_add_expr_to_block (&block, tmp);
2545
2546 tmp = build1_v (LABEL_EXPR, end_label);
2547 gfc_add_expr_to_block (&block, tmp);
2548
2549 return gfc_finish_block (&block);
2550 }
2551 }
2552
2553 if (code->expr1->ts.kind == 1)
2554 k = 0;
2555 else if (code->expr1->ts.kind == 4)
2556 k = 1;
2557 else
2558 gcc_unreachable ();
2559
2560 if (select_struct[k] == NULL)
2561 {
2562 tree *chain = NULL;
2563 select_struct[k] = make_node (RECORD_TYPE);
2564
2565 if (code->expr1->ts.kind == 1)
2566 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char1");
2567 else if (code->expr1->ts.kind == 4)
2568 TYPE_NAME (select_struct[k]) = get_identifier ("_jump_struct_char4");
2569 else
2570 gcc_unreachable ();
2571
2572 #undef ADD_FIELD
2573 #define ADD_FIELD(NAME, TYPE) \
2574 ss_##NAME[k] = gfc_add_field_to_struct (select_struct[k], \
2575 get_identifier (stringize(NAME)), \
2576 TYPE, \
2577 &chain)
2578
2579 ADD_FIELD (string1, pchartype);
2580 ADD_FIELD (string1_len, gfc_charlen_type_node);
2581
2582 ADD_FIELD (string2, pchartype);
2583 ADD_FIELD (string2_len, gfc_charlen_type_node);
2584
2585 ADD_FIELD (target, integer_type_node);
2586 #undef ADD_FIELD
2587
2588 gfc_finish_type (select_struct[k]);
2589 }
2590
2591 n = 0;
2592 for (d = cp; d; d = d->right)
2593 d->n = n++;
2594
2595 for (c = code->block; c; c = c->block)
2596 {
2597 for (d = c->ext.block.case_list; d; d = d->next)
2598 {
2599 label = gfc_build_label_decl (NULL_TREE);
2600 tmp = build_case_label ((d->low == NULL && d->high == NULL)
2601 ? NULL
2602 : build_int_cst (integer_type_node, d->n),
2603 NULL, label);
2604 gfc_add_expr_to_block (&body, tmp);
2605 }
2606
2607 tmp = gfc_trans_code (c->next);
2608 gfc_add_expr_to_block (&body, tmp);
2609
2610 tmp = build1_v (GOTO_EXPR, end_label);
2611 gfc_add_expr_to_block (&body, tmp);
2612 }
2613
2614 /* Generate the structure describing the branches */
2615 for (d = cp; d; d = d->right)
2616 {
2617 vec<constructor_elt, va_gc> *node = NULL;
2618
2619 gfc_init_se (&se, NULL);
2620
2621 if (d->low == NULL)
2622 {
2623 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], null_pointer_node);
2624 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], integer_zero_node);
2625 }
2626 else
2627 {
2628 gfc_conv_expr_reference (&se, d->low);
2629
2630 CONSTRUCTOR_APPEND_ELT (node, ss_string1[k], se.expr);
2631 CONSTRUCTOR_APPEND_ELT (node, ss_string1_len[k], se.string_length);
2632 }
2633
2634 if (d->high == NULL)
2635 {
2636 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], null_pointer_node);
2637 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], integer_zero_node);
2638 }
2639 else
2640 {
2641 gfc_init_se (&se, NULL);
2642 gfc_conv_expr_reference (&se, d->high);
2643
2644 CONSTRUCTOR_APPEND_ELT (node, ss_string2[k], se.expr);
2645 CONSTRUCTOR_APPEND_ELT (node, ss_string2_len[k], se.string_length);
2646 }
2647
2648 CONSTRUCTOR_APPEND_ELT (node, ss_target[k],
2649 build_int_cst (integer_type_node, d->n));
2650
2651 tmp = build_constructor (select_struct[k], node);
2652 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, tmp);
2653 }
2654
2655 type = build_array_type (select_struct[k],
2656 build_index_type (size_int (n-1)));
2657
2658 init = build_constructor (type, inits);
2659 TREE_CONSTANT (init) = 1;
2660 TREE_STATIC (init) = 1;
2661 /* Create a static variable to hold the jump table. */
2662 tmp = gfc_create_var (type, "jumptable");
2663 TREE_CONSTANT (tmp) = 1;
2664 TREE_STATIC (tmp) = 1;
2665 TREE_READONLY (tmp) = 1;
2666 DECL_INITIAL (tmp) = init;
2667 init = tmp;
2668
2669 /* Build the library call */
2670 init = gfc_build_addr_expr (pvoid_type_node, init);
2671
2672 if (code->expr1->ts.kind == 1)
2673 fndecl = gfor_fndecl_select_string;
2674 else if (code->expr1->ts.kind == 4)
2675 fndecl = gfor_fndecl_select_string_char4;
2676 else
2677 gcc_unreachable ();
2678
2679 tmp = build_call_expr_loc (input_location,
2680 fndecl, 4, init,
2681 build_int_cst (gfc_charlen_type_node, n),
2682 expr1se.expr, expr1se.string_length);
2683 case_num = gfc_create_var (integer_type_node, "case_num");
2684 gfc_add_modify (&block, case_num, tmp);
2685
2686 gfc_add_block_to_block (&block, &expr1se.post);
2687
2688 tmp = gfc_finish_block (&body);
2689 tmp = fold_build3_loc (input_location, SWITCH_EXPR, NULL_TREE,
2690 case_num, tmp, NULL_TREE);
2691 gfc_add_expr_to_block (&block, tmp);
2692
2693 tmp = build1_v (LABEL_EXPR, end_label);
2694 gfc_add_expr_to_block (&block, tmp);
2695
2696 return gfc_finish_block (&block);
2697 }
2698
2699
2700 /* Translate the three variants of the SELECT CASE construct.
2701
2702 SELECT CASEs with INTEGER case expressions can be translated to an
2703 equivalent GENERIC switch statement, and for LOGICAL case
2704 expressions we build one or two if-else compares.
2705
2706 SELECT CASEs with CHARACTER case expressions are a whole different
2707 story, because they don't exist in GENERIC. So we sort them and
2708 do a binary search at runtime.
2709
2710 Fortran has no BREAK statement, and it does not allow jumps from
2711 one case block to another. That makes things a lot easier for
2712 the optimizers. */
2713
2714 tree
2715 gfc_trans_select (gfc_code * code)
2716 {
2717 stmtblock_t block;
2718 tree body;
2719 tree exit_label;
2720
2721 gcc_assert (code && code->expr1);
2722 gfc_init_block (&block);
2723
2724 /* Build the exit label and hang it in. */
2725 exit_label = gfc_build_label_decl (NULL_TREE);
2726 code->exit_label = exit_label;
2727
2728 /* Empty SELECT constructs are legal. */
2729 if (code->block == NULL)
2730 body = build_empty_stmt (input_location);
2731
2732 /* Select the correct translation function. */
2733 else
2734 switch (code->expr1->ts.type)
2735 {
2736 case BT_LOGICAL:
2737 body = gfc_trans_logical_select (code);
2738 break;
2739
2740 case BT_INTEGER:
2741 body = gfc_trans_integer_select (code);
2742 break;
2743
2744 case BT_CHARACTER:
2745 body = gfc_trans_character_select (code);
2746 break;
2747
2748 default:
2749 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
2750 /* Not reached */
2751 }
2752
2753 /* Build everything together. */
2754 gfc_add_expr_to_block (&block, body);
2755 gfc_add_expr_to_block (&block, build1_v (LABEL_EXPR, exit_label));
2756
2757 return gfc_finish_block (&block);
2758 }
2759
2760
2761 /* Traversal function to substitute a replacement symtree if the symbol
2762 in the expression is the same as that passed. f == 2 signals that
2763 that variable itself is not to be checked - only the references.
2764 This group of functions is used when the variable expression in a
2765 FORALL assignment has internal references. For example:
2766 FORALL (i = 1:4) p(p(i)) = i
2767 The only recourse here is to store a copy of 'p' for the index
2768 expression. */
2769
2770 static gfc_symtree *new_symtree;
2771 static gfc_symtree *old_symtree;
2772
2773 static bool
2774 forall_replace (gfc_expr *expr, gfc_symbol *sym, int *f)
2775 {
2776 if (expr->expr_type != EXPR_VARIABLE)
2777 return false;
2778
2779 if (*f == 2)
2780 *f = 1;
2781 else if (expr->symtree->n.sym == sym)
2782 expr->symtree = new_symtree;
2783
2784 return false;
2785 }
2786
2787 static void
2788 forall_replace_symtree (gfc_expr *e, gfc_symbol *sym, int f)
2789 {
2790 gfc_traverse_expr (e, sym, forall_replace, f);
2791 }
2792
2793 static bool
2794 forall_restore (gfc_expr *expr,
2795 gfc_symbol *sym ATTRIBUTE_UNUSED,
2796 int *f ATTRIBUTE_UNUSED)
2797 {
2798 if (expr->expr_type != EXPR_VARIABLE)
2799 return false;
2800
2801 if (expr->symtree == new_symtree)
2802 expr->symtree = old_symtree;
2803
2804 return false;
2805 }
2806
2807 static void
2808 forall_restore_symtree (gfc_expr *e)
2809 {
2810 gfc_traverse_expr (e, NULL, forall_restore, 0);
2811 }
2812
2813 static void
2814 forall_make_variable_temp (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
2815 {
2816 gfc_se tse;
2817 gfc_se rse;
2818 gfc_expr *e;
2819 gfc_symbol *new_sym;
2820 gfc_symbol *old_sym;
2821 gfc_symtree *root;
2822 tree tmp;
2823
2824 /* Build a copy of the lvalue. */
2825 old_symtree = c->expr1->symtree;
2826 old_sym = old_symtree->n.sym;
2827 e = gfc_lval_expr_from_sym (old_sym);
2828 if (old_sym->attr.dimension)
2829 {
2830 gfc_init_se (&tse, NULL);
2831 gfc_conv_subref_array_arg (&tse, e, 0, INTENT_IN, false);
2832 gfc_add_block_to_block (pre, &tse.pre);
2833 gfc_add_block_to_block (post, &tse.post);
2834 tse.expr = build_fold_indirect_ref_loc (input_location, tse.expr);
2835
2836 if (e->ts.type != BT_CHARACTER)
2837 {
2838 /* Use the variable offset for the temporary. */
2839 tmp = gfc_conv_array_offset (old_sym->backend_decl);
2840 gfc_conv_descriptor_offset_set (pre, tse.expr, tmp);
2841 }
2842 }
2843 else
2844 {
2845 gfc_init_se (&tse, NULL);
2846 gfc_init_se (&rse, NULL);
2847 gfc_conv_expr (&rse, e);
2848 if (e->ts.type == BT_CHARACTER)
2849 {
2850 tse.string_length = rse.string_length;
2851 tmp = gfc_get_character_type_len (gfc_default_character_kind,
2852 tse.string_length);
2853 tse.expr = gfc_conv_string_tmp (&tse, build_pointer_type (tmp),
2854 rse.string_length);
2855 gfc_add_block_to_block (pre, &tse.pre);
2856 gfc_add_block_to_block (post, &tse.post);
2857 }
2858 else
2859 {
2860 tmp = gfc_typenode_for_spec (&e->ts);
2861 tse.expr = gfc_create_var (tmp, "temp");
2862 }
2863
2864 tmp = gfc_trans_scalar_assign (&tse, &rse, e->ts, true,
2865 e->expr_type == EXPR_VARIABLE, true);
2866 gfc_add_expr_to_block (pre, tmp);
2867 }
2868 gfc_free_expr (e);
2869
2870 /* Create a new symbol to represent the lvalue. */
2871 new_sym = gfc_new_symbol (old_sym->name, NULL);
2872 new_sym->ts = old_sym->ts;
2873 new_sym->attr.referenced = 1;
2874 new_sym->attr.temporary = 1;
2875 new_sym->attr.dimension = old_sym->attr.dimension;
2876 new_sym->attr.flavor = old_sym->attr.flavor;
2877
2878 /* Use the temporary as the backend_decl. */
2879 new_sym->backend_decl = tse.expr;
2880
2881 /* Create a fake symtree for it. */
2882 root = NULL;
2883 new_symtree = gfc_new_symtree (&root, old_sym->name);
2884 new_symtree->n.sym = new_sym;
2885 gcc_assert (new_symtree == root);
2886
2887 /* Go through the expression reference replacing the old_symtree
2888 with the new. */
2889 forall_replace_symtree (c->expr1, old_sym, 2);
2890
2891 /* Now we have made this temporary, we might as well use it for
2892 the right hand side. */
2893 forall_replace_symtree (c->expr2, old_sym, 1);
2894 }
2895
2896
2897 /* Handles dependencies in forall assignments. */
2898 static int
2899 check_forall_dependencies (gfc_code *c, stmtblock_t *pre, stmtblock_t *post)
2900 {
2901 gfc_ref *lref;
2902 gfc_ref *rref;
2903 int need_temp;
2904 gfc_symbol *lsym;
2905
2906 lsym = c->expr1->symtree->n.sym;
2907 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
2908
2909 /* Now check for dependencies within the 'variable'
2910 expression itself. These are treated by making a complete
2911 copy of variable and changing all the references to it
2912 point to the copy instead. Note that the shallow copy of
2913 the variable will not suffice for derived types with
2914 pointer components. We therefore leave these to their
2915 own devices. */
2916 if (lsym->ts.type == BT_DERIVED
2917 && lsym->ts.u.derived->attr.pointer_comp)
2918 return need_temp;
2919
2920 new_symtree = NULL;
2921 if (find_forall_index (c->expr1, lsym, 2))
2922 {
2923 forall_make_variable_temp (c, pre, post);
2924 need_temp = 0;
2925 }
2926
2927 /* Substrings with dependencies are treated in the same
2928 way. */
2929 if (c->expr1->ts.type == BT_CHARACTER
2930 && c->expr1->ref
2931 && c->expr2->expr_type == EXPR_VARIABLE
2932 && lsym == c->expr2->symtree->n.sym)
2933 {
2934 for (lref = c->expr1->ref; lref; lref = lref->next)
2935 if (lref->type == REF_SUBSTRING)
2936 break;
2937 for (rref = c->expr2->ref; rref; rref = rref->next)
2938 if (rref->type == REF_SUBSTRING)
2939 break;
2940
2941 if (rref && lref
2942 && gfc_dep_compare_expr (rref->u.ss.start, lref->u.ss.start) < 0)
2943 {
2944 forall_make_variable_temp (c, pre, post);
2945 need_temp = 0;
2946 }
2947 }
2948 return need_temp;
2949 }
2950
2951
2952 static void
2953 cleanup_forall_symtrees (gfc_code *c)
2954 {
2955 forall_restore_symtree (c->expr1);
2956 forall_restore_symtree (c->expr2);
2957 free (new_symtree->n.sym);
2958 free (new_symtree);
2959 }
2960
2961
2962 /* Generate the loops for a FORALL block, specified by FORALL_TMP. BODY
2963 is the contents of the FORALL block/stmt to be iterated. MASK_FLAG
2964 indicates whether we should generate code to test the FORALLs mask
2965 array. OUTER is the loop header to be used for initializing mask
2966 indices.
2967
2968 The generated loop format is:
2969 count = (end - start + step) / step
2970 loopvar = start
2971 while (1)
2972 {
2973 if (count <=0 )
2974 goto end_of_loop
2975 <body>
2976 loopvar += step
2977 count --
2978 }
2979 end_of_loop: */
2980
2981 static tree
2982 gfc_trans_forall_loop (forall_info *forall_tmp, tree body,
2983 int mask_flag, stmtblock_t *outer)
2984 {
2985 int n, nvar;
2986 tree tmp;
2987 tree cond;
2988 stmtblock_t block;
2989 tree exit_label;
2990 tree count;
2991 tree var, start, end, step;
2992 iter_info *iter;
2993
2994 /* Initialize the mask index outside the FORALL nest. */
2995 if (mask_flag && forall_tmp->mask)
2996 gfc_add_modify (outer, forall_tmp->maskindex, gfc_index_zero_node);
2997
2998 iter = forall_tmp->this_loop;
2999 nvar = forall_tmp->nvar;
3000 for (n = 0; n < nvar; n++)
3001 {
3002 var = iter->var;
3003 start = iter->start;
3004 end = iter->end;
3005 step = iter->step;
3006
3007 exit_label = gfc_build_label_decl (NULL_TREE);
3008 TREE_USED (exit_label) = 1;
3009
3010 /* The loop counter. */
3011 count = gfc_create_var (TREE_TYPE (var), "count");
3012
3013 /* The body of the loop. */
3014 gfc_init_block (&block);
3015
3016 /* The exit condition. */
3017 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3018 count, build_int_cst (TREE_TYPE (count), 0));
3019 if (forall_tmp->do_concurrent)
3020 cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
3021 build_int_cst (integer_type_node,
3022 annot_expr_ivdep_kind));
3023
3024 tmp = build1_v (GOTO_EXPR, exit_label);
3025 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3026 cond, tmp, build_empty_stmt (input_location));
3027 gfc_add_expr_to_block (&block, tmp);
3028
3029 /* The main loop body. */
3030 gfc_add_expr_to_block (&block, body);
3031
3032 /* Increment the loop variable. */
3033 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), var,
3034 step);
3035 gfc_add_modify (&block, var, tmp);
3036
3037 /* Advance to the next mask element. Only do this for the
3038 innermost loop. */
3039 if (n == 0 && mask_flag && forall_tmp->mask)
3040 {
3041 tree maskindex = forall_tmp->maskindex;
3042 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3043 maskindex, gfc_index_one_node);
3044 gfc_add_modify (&block, maskindex, tmp);
3045 }
3046
3047 /* Decrement the loop counter. */
3048 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), count,
3049 build_int_cst (TREE_TYPE (var), 1));
3050 gfc_add_modify (&block, count, tmp);
3051
3052 body = gfc_finish_block (&block);
3053
3054 /* Loop var initialization. */
3055 gfc_init_block (&block);
3056 gfc_add_modify (&block, var, start);
3057
3058
3059 /* Initialize the loop counter. */
3060 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (var), step,
3061 start);
3062 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (var), end,
3063 tmp);
3064 tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR, TREE_TYPE (var),
3065 tmp, step);
3066 gfc_add_modify (&block, count, tmp);
3067
3068 /* The loop expression. */
3069 tmp = build1_v (LOOP_EXPR, body);
3070 gfc_add_expr_to_block (&block, tmp);
3071
3072 /* The exit label. */
3073 tmp = build1_v (LABEL_EXPR, exit_label);
3074 gfc_add_expr_to_block (&block, tmp);
3075
3076 body = gfc_finish_block (&block);
3077 iter = iter->next;
3078 }
3079 return body;
3080 }
3081
3082
3083 /* Generate the body and loops according to MASK_FLAG. If MASK_FLAG
3084 is nonzero, the body is controlled by all masks in the forall nest.
3085 Otherwise, the innermost loop is not controlled by it's mask. This
3086 is used for initializing that mask. */
3087
3088 static tree
3089 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
3090 int mask_flag)
3091 {
3092 tree tmp;
3093 stmtblock_t header;
3094 forall_info *forall_tmp;
3095 tree mask, maskindex;
3096
3097 gfc_start_block (&header);
3098
3099 forall_tmp = nested_forall_info;
3100 while (forall_tmp != NULL)
3101 {
3102 /* Generate body with masks' control. */
3103 if (mask_flag)
3104 {
3105 mask = forall_tmp->mask;
3106 maskindex = forall_tmp->maskindex;
3107
3108 /* If a mask was specified make the assignment conditional. */
3109 if (mask)
3110 {
3111 tmp = gfc_build_array_ref (mask, maskindex, NULL);
3112 body = build3_v (COND_EXPR, tmp, body,
3113 build_empty_stmt (input_location));
3114 }
3115 }
3116 body = gfc_trans_forall_loop (forall_tmp, body, mask_flag, &header);
3117 forall_tmp = forall_tmp->prev_nest;
3118 mask_flag = 1;
3119 }
3120
3121 gfc_add_expr_to_block (&header, body);
3122 return gfc_finish_block (&header);
3123 }
3124
3125
3126 /* Allocate data for holding a temporary array. Returns either a local
3127 temporary array or a pointer variable. */
3128
3129 static tree
3130 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
3131 tree elem_type)
3132 {
3133 tree tmpvar;
3134 tree type;
3135 tree tmp;
3136
3137 if (INTEGER_CST_P (size))
3138 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3139 size, gfc_index_one_node);
3140 else
3141 tmp = NULL_TREE;
3142
3143 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
3144 type = build_array_type (elem_type, type);
3145 if (gfc_can_put_var_on_stack (bytesize))
3146 {
3147 gcc_assert (INTEGER_CST_P (size));
3148 tmpvar = gfc_create_var (type, "temp");
3149 *pdata = NULL_TREE;
3150 }
3151 else
3152 {
3153 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
3154 *pdata = convert (pvoid_type_node, tmpvar);
3155
3156 tmp = gfc_call_malloc (pblock, TREE_TYPE (tmpvar), bytesize);
3157 gfc_add_modify (pblock, tmpvar, tmp);
3158 }
3159 return tmpvar;
3160 }
3161
3162
3163 /* Generate codes to copy the temporary to the actual lhs. */
3164
3165 static tree
3166 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
3167 tree count1, tree wheremask, bool invert)
3168 {
3169 gfc_ss *lss;
3170 gfc_se lse, rse;
3171 stmtblock_t block, body;
3172 gfc_loopinfo loop1;
3173 tree tmp;
3174 tree wheremaskexpr;
3175
3176 /* Walk the lhs. */
3177 lss = gfc_walk_expr (expr);
3178
3179 if (lss == gfc_ss_terminator)
3180 {
3181 gfc_start_block (&block);
3182
3183 gfc_init_se (&lse, NULL);
3184
3185 /* Translate the expression. */
3186 gfc_conv_expr (&lse, expr);
3187
3188 /* Form the expression for the temporary. */
3189 tmp = gfc_build_array_ref (tmp1, count1, NULL);
3190
3191 /* Use the scalar assignment as is. */
3192 gfc_add_block_to_block (&block, &lse.pre);
3193 gfc_add_modify (&block, lse.expr, tmp);
3194 gfc_add_block_to_block (&block, &lse.post);
3195
3196 /* Increment the count1. */
3197 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3198 count1, gfc_index_one_node);
3199 gfc_add_modify (&block, count1, tmp);
3200
3201 tmp = gfc_finish_block (&block);
3202 }
3203 else
3204 {
3205 gfc_start_block (&block);
3206
3207 gfc_init_loopinfo (&loop1);
3208 gfc_init_se (&rse, NULL);
3209 gfc_init_se (&lse, NULL);
3210
3211 /* Associate the lss with the loop. */
3212 gfc_add_ss_to_loop (&loop1, lss);
3213
3214 /* Calculate the bounds of the scalarization. */
3215 gfc_conv_ss_startstride (&loop1);
3216 /* Setup the scalarizing loops. */
3217 gfc_conv_loop_setup (&loop1, &expr->where);
3218
3219 gfc_mark_ss_chain_used (lss, 1);
3220
3221 /* Start the scalarized loop body. */
3222 gfc_start_scalarized_body (&loop1, &body);
3223
3224 /* Setup the gfc_se structures. */
3225 gfc_copy_loopinfo_to_se (&lse, &loop1);
3226 lse.ss = lss;
3227
3228 /* Form the expression of the temporary. */
3229 if (lss != gfc_ss_terminator)
3230 rse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3231 /* Translate expr. */
3232 gfc_conv_expr (&lse, expr);
3233
3234 /* Use the scalar assignment. */
3235 rse.string_length = lse.string_length;
3236 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts, false, true, true);
3237
3238 /* Form the mask expression according to the mask tree list. */
3239 if (wheremask)
3240 {
3241 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3242 if (invert)
3243 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3244 TREE_TYPE (wheremaskexpr),
3245 wheremaskexpr);
3246 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3247 wheremaskexpr, tmp,
3248 build_empty_stmt (input_location));
3249 }
3250
3251 gfc_add_expr_to_block (&body, tmp);
3252
3253 /* Increment count1. */
3254 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3255 count1, gfc_index_one_node);
3256 gfc_add_modify (&body, count1, tmp);
3257
3258 /* Increment count3. */
3259 if (count3)
3260 {
3261 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3262 gfc_array_index_type, count3,
3263 gfc_index_one_node);
3264 gfc_add_modify (&body, count3, tmp);
3265 }
3266
3267 /* Generate the copying loops. */
3268 gfc_trans_scalarizing_loops (&loop1, &body);
3269 gfc_add_block_to_block (&block, &loop1.pre);
3270 gfc_add_block_to_block (&block, &loop1.post);
3271 gfc_cleanup_loop (&loop1);
3272
3273 tmp = gfc_finish_block (&block);
3274 }
3275 return tmp;
3276 }
3277
3278
3279 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
3280 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
3281 and should not be freed. WHEREMASK is the conditional execution mask
3282 whose sense may be inverted by INVERT. */
3283
3284 static tree
3285 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
3286 tree count1, gfc_ss *lss, gfc_ss *rss,
3287 tree wheremask, bool invert)
3288 {
3289 stmtblock_t block, body1;
3290 gfc_loopinfo loop;
3291 gfc_se lse;
3292 gfc_se rse;
3293 tree tmp;
3294 tree wheremaskexpr;
3295
3296 gfc_start_block (&block);
3297
3298 gfc_init_se (&rse, NULL);
3299 gfc_init_se (&lse, NULL);
3300
3301 if (lss == gfc_ss_terminator)
3302 {
3303 gfc_init_block (&body1);
3304 gfc_conv_expr (&rse, expr2);
3305 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3306 }
3307 else
3308 {
3309 /* Initialize the loop. */
3310 gfc_init_loopinfo (&loop);
3311
3312 /* We may need LSS to determine the shape of the expression. */
3313 gfc_add_ss_to_loop (&loop, lss);
3314 gfc_add_ss_to_loop (&loop, rss);
3315
3316 gfc_conv_ss_startstride (&loop);
3317 gfc_conv_loop_setup (&loop, &expr2->where);
3318
3319 gfc_mark_ss_chain_used (rss, 1);
3320 /* Start the loop body. */
3321 gfc_start_scalarized_body (&loop, &body1);
3322
3323 /* Translate the expression. */
3324 gfc_copy_loopinfo_to_se (&rse, &loop);
3325 rse.ss = rss;
3326 gfc_conv_expr (&rse, expr2);
3327
3328 /* Form the expression of the temporary. */
3329 lse.expr = gfc_build_array_ref (tmp1, count1, NULL);
3330 }
3331
3332 /* Use the scalar assignment. */
3333 lse.string_length = rse.string_length;
3334 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts, true,
3335 expr2->expr_type == EXPR_VARIABLE, true);
3336
3337 /* Form the mask expression according to the mask tree list. */
3338 if (wheremask)
3339 {
3340 wheremaskexpr = gfc_build_array_ref (wheremask, count3, NULL);
3341 if (invert)
3342 wheremaskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
3343 TREE_TYPE (wheremaskexpr),
3344 wheremaskexpr);
3345 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3346 wheremaskexpr, tmp,
3347 build_empty_stmt (input_location));
3348 }
3349
3350 gfc_add_expr_to_block (&body1, tmp);
3351
3352 if (lss == gfc_ss_terminator)
3353 {
3354 gfc_add_block_to_block (&block, &body1);
3355
3356 /* Increment count1. */
3357 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (count1),
3358 count1, gfc_index_one_node);
3359 gfc_add_modify (&block, count1, tmp);
3360 }
3361 else
3362 {
3363 /* Increment count1. */
3364 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3365 count1, gfc_index_one_node);
3366 gfc_add_modify (&body1, count1, tmp);
3367
3368 /* Increment count3. */
3369 if (count3)
3370 {
3371 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3372 gfc_array_index_type,
3373 count3, gfc_index_one_node);
3374 gfc_add_modify (&body1, count3, tmp);
3375 }
3376
3377 /* Generate the copying loops. */
3378 gfc_trans_scalarizing_loops (&loop, &body1);
3379
3380 gfc_add_block_to_block (&block, &loop.pre);
3381 gfc_add_block_to_block (&block, &loop.post);
3382
3383 gfc_cleanup_loop (&loop);
3384 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
3385 as tree nodes in SS may not be valid in different scope. */
3386 }
3387
3388 tmp = gfc_finish_block (&block);
3389 return tmp;
3390 }
3391
3392
3393 /* Calculate the size of temporary needed in the assignment inside forall.
3394 LSS and RSS are filled in this function. */
3395
3396 static tree
3397 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
3398 stmtblock_t * pblock,
3399 gfc_ss **lss, gfc_ss **rss)
3400 {
3401 gfc_loopinfo loop;
3402 tree size;
3403 int i;
3404 int save_flag;
3405 tree tmp;
3406
3407 *lss = gfc_walk_expr (expr1);
3408 *rss = NULL;
3409
3410 size = gfc_index_one_node;
3411 if (*lss != gfc_ss_terminator)
3412 {
3413 gfc_init_loopinfo (&loop);
3414
3415 /* Walk the RHS of the expression. */
3416 *rss = gfc_walk_expr (expr2);
3417 if (*rss == gfc_ss_terminator)
3418 /* The rhs is scalar. Add a ss for the expression. */
3419 *rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
3420
3421 /* Associate the SS with the loop. */
3422 gfc_add_ss_to_loop (&loop, *lss);
3423 /* We don't actually need to add the rhs at this point, but it might
3424 make guessing the loop bounds a bit easier. */
3425 gfc_add_ss_to_loop (&loop, *rss);
3426
3427 /* We only want the shape of the expression, not rest of the junk
3428 generated by the scalarizer. */
3429 loop.array_parameter = 1;
3430
3431 /* Calculate the bounds of the scalarization. */
3432 save_flag = gfc_option.rtcheck;
3433 gfc_option.rtcheck &= ~GFC_RTCHECK_BOUNDS;
3434 gfc_conv_ss_startstride (&loop);
3435 gfc_option.rtcheck = save_flag;
3436 gfc_conv_loop_setup (&loop, &expr2->where);
3437
3438 /* Figure out how many elements we need. */
3439 for (i = 0; i < loop.dimen; i++)
3440 {
3441 tmp = fold_build2_loc (input_location, MINUS_EXPR,
3442 gfc_array_index_type,
3443 gfc_index_one_node, loop.from[i]);
3444 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3445 gfc_array_index_type, tmp, loop.to[i]);
3446 size = fold_build2_loc (input_location, MULT_EXPR,
3447 gfc_array_index_type, size, tmp);
3448 }
3449 gfc_add_block_to_block (pblock, &loop.pre);
3450 size = gfc_evaluate_now (size, pblock);
3451 gfc_add_block_to_block (pblock, &loop.post);
3452
3453 /* TODO: write a function that cleans up a loopinfo without freeing
3454 the SS chains. Currently a NOP. */
3455 }
3456
3457 return size;
3458 }
3459
3460
3461 /* Calculate the overall iterator number of the nested forall construct.
3462 This routine actually calculates the number of times the body of the
3463 nested forall specified by NESTED_FORALL_INFO is executed and multiplies
3464 that by the expression INNER_SIZE. The BLOCK argument specifies the
3465 block in which to calculate the result, and the optional INNER_SIZE_BODY
3466 argument contains any statements that need to executed (inside the loop)
3467 to initialize or calculate INNER_SIZE. */
3468
3469 static tree
3470 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
3471 stmtblock_t *inner_size_body, stmtblock_t *block)
3472 {
3473 forall_info *forall_tmp = nested_forall_info;
3474 tree tmp, number;
3475 stmtblock_t body;
3476
3477 /* We can eliminate the innermost unconditional loops with constant
3478 array bounds. */
3479 if (INTEGER_CST_P (inner_size))
3480 {
3481 while (forall_tmp
3482 && !forall_tmp->mask
3483 && INTEGER_CST_P (forall_tmp->size))
3484 {
3485 inner_size = fold_build2_loc (input_location, MULT_EXPR,
3486 gfc_array_index_type,
3487 inner_size, forall_tmp->size);
3488 forall_tmp = forall_tmp->prev_nest;
3489 }
3490
3491 /* If there are no loops left, we have our constant result. */
3492 if (!forall_tmp)
3493 return inner_size;
3494 }
3495
3496 /* Otherwise, create a temporary variable to compute the result. */
3497 number = gfc_create_var (gfc_array_index_type, "num");
3498 gfc_add_modify (block, number, gfc_index_zero_node);
3499
3500 gfc_start_block (&body);
3501 if (inner_size_body)
3502 gfc_add_block_to_block (&body, inner_size_body);
3503 if (forall_tmp)
3504 tmp = fold_build2_loc (input_location, PLUS_EXPR,
3505 gfc_array_index_type, number, inner_size);
3506 else
3507 tmp = inner_size;
3508 gfc_add_modify (&body, number, tmp);
3509 tmp = gfc_finish_block (&body);
3510
3511 /* Generate loops. */
3512 if (forall_tmp != NULL)
3513 tmp = gfc_trans_nested_forall_loop (forall_tmp, tmp, 1);
3514
3515 gfc_add_expr_to_block (block, tmp);
3516
3517 return number;
3518 }
3519
3520
3521 /* Allocate temporary for forall construct. SIZE is the size of temporary
3522 needed. PTEMP1 is returned for space free. */
3523
3524 static tree
3525 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
3526 tree * ptemp1)
3527 {
3528 tree bytesize;
3529 tree unit;
3530 tree tmp;
3531
3532 unit = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (type));
3533 if (!integer_onep (unit))
3534 bytesize = fold_build2_loc (input_location, MULT_EXPR,
3535 gfc_array_index_type, size, unit);
3536 else
3537 bytesize = size;
3538
3539 *ptemp1 = NULL;
3540 tmp = gfc_do_allocate (bytesize, size, ptemp1, block, type);
3541
3542 if (*ptemp1)
3543 tmp = build_fold_indirect_ref_loc (input_location, tmp);
3544 return tmp;
3545 }
3546
3547
3548 /* Allocate temporary for forall construct according to the information in
3549 nested_forall_info. INNER_SIZE is the size of temporary needed in the
3550 assignment inside forall. PTEMP1 is returned for space free. */
3551
3552 static tree
3553 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
3554 tree inner_size, stmtblock_t * inner_size_body,
3555 stmtblock_t * block, tree * ptemp1)
3556 {
3557 tree size;
3558
3559 /* Calculate the total size of temporary needed in forall construct. */
3560 size = compute_overall_iter_number (nested_forall_info, inner_size,
3561 inner_size_body, block);
3562
3563 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
3564 }
3565
3566
3567 /* Handle assignments inside forall which need temporary.
3568
3569 forall (i=start:end:stride; maskexpr)
3570 e<i> = f<i>
3571 end forall
3572 (where e,f<i> are arbitrary expressions possibly involving i
3573 and there is a dependency between e<i> and f<i>)
3574 Translates to:
3575 masktmp(:) = maskexpr(:)
3576
3577 maskindex = 0;
3578 count1 = 0;
3579 num = 0;
3580 for (i = start; i <= end; i += stride)
3581 num += SIZE (f<i>)
3582 count1 = 0;
3583 ALLOCATE (tmp(num))
3584 for (i = start; i <= end; i += stride)
3585 {
3586 if (masktmp[maskindex++])
3587 tmp[count1++] = f<i>
3588 }
3589 maskindex = 0;
3590 count1 = 0;
3591 for (i = start; i <= end; i += stride)
3592 {
3593 if (masktmp[maskindex++])
3594 e<i> = tmp[count1++]
3595 }
3596 DEALLOCATE (tmp)
3597 */
3598 static void
3599 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3600 tree wheremask, bool invert,
3601 forall_info * nested_forall_info,
3602 stmtblock_t * block)
3603 {
3604 tree type;
3605 tree inner_size;
3606 gfc_ss *lss, *rss;
3607 tree count, count1;
3608 tree tmp, tmp1;
3609 tree ptemp1;
3610 stmtblock_t inner_size_body;
3611
3612 /* Create vars. count1 is the current iterator number of the nested
3613 forall. */
3614 count1 = gfc_create_var (gfc_array_index_type, "count1");
3615
3616 /* Count is the wheremask index. */
3617 if (wheremask)
3618 {
3619 count = gfc_create_var (gfc_array_index_type, "count");
3620 gfc_add_modify (block, count, gfc_index_zero_node);
3621 }
3622 else
3623 count = NULL;
3624
3625 /* Initialize count1. */
3626 gfc_add_modify (block, count1, gfc_index_zero_node);
3627
3628 /* Calculate the size of temporary needed in the assignment. Return loop, lss
3629 and rss which are used in function generate_loop_for_rhs_to_temp(). */
3630 gfc_init_block (&inner_size_body);
3631 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
3632 &lss, &rss);
3633
3634 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
3635 if (expr1->ts.type == BT_CHARACTER && expr1->ts.u.cl->length)
3636 {
3637 if (!expr1->ts.u.cl->backend_decl)
3638 {
3639 gfc_se tse;
3640 gfc_init_se (&tse, NULL);
3641 gfc_conv_expr (&tse, expr1->ts.u.cl->length);
3642 expr1->ts.u.cl->backend_decl = tse.expr;
3643 }
3644 type = gfc_get_character_type_len (gfc_default_character_kind,
3645 expr1->ts.u.cl->backend_decl);
3646 }
3647 else
3648 type = gfc_typenode_for_spec (&expr1->ts);
3649
3650 /* Allocate temporary for nested forall construct according to the
3651 information in nested_forall_info and inner_size. */
3652 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
3653 &inner_size_body, block, &ptemp1);
3654
3655 /* Generate codes to copy rhs to the temporary . */
3656 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
3657 wheremask, invert);
3658
3659 /* Generate body and loops according to the information in
3660 nested_forall_info. */
3661 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3662 gfc_add_expr_to_block (block, tmp);
3663
3664 /* Reset count1. */
3665 gfc_add_modify (block, count1, gfc_index_zero_node);
3666
3667 /* Reset count. */
3668 if (wheremask)
3669 gfc_add_modify (block, count, gfc_index_zero_node);
3670
3671 /* Generate codes to copy the temporary to lhs. */
3672 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1,
3673 wheremask, invert);
3674
3675 /* Generate body and loops according to the information in
3676 nested_forall_info. */
3677 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3678 gfc_add_expr_to_block (block, tmp);
3679
3680 if (ptemp1)
3681 {
3682 /* Free the temporary. */
3683 tmp = gfc_call_free (ptemp1);
3684 gfc_add_expr_to_block (block, tmp);
3685 }
3686 }
3687
3688
3689 /* Translate pointer assignment inside FORALL which need temporary. */
3690
3691 static void
3692 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
3693 forall_info * nested_forall_info,
3694 stmtblock_t * block)
3695 {
3696 tree type;
3697 tree inner_size;
3698 gfc_ss *lss, *rss;
3699 gfc_se lse;
3700 gfc_se rse;
3701 gfc_array_info *info;
3702 gfc_loopinfo loop;
3703 tree desc;
3704 tree parm;
3705 tree parmtype;
3706 stmtblock_t body;
3707 tree count;
3708 tree tmp, tmp1, ptemp1;
3709
3710 count = gfc_create_var (gfc_array_index_type, "count");
3711 gfc_add_modify (block, count, gfc_index_zero_node);
3712
3713 inner_size = gfc_index_one_node;
3714 lss = gfc_walk_expr (expr1);
3715 rss = gfc_walk_expr (expr2);
3716 if (lss == gfc_ss_terminator)
3717 {
3718 type = gfc_typenode_for_spec (&expr1->ts);
3719 type = build_pointer_type (type);
3720
3721 /* Allocate temporary for nested forall construct according to the
3722 information in nested_forall_info and inner_size. */
3723 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
3724 inner_size, NULL, block, &ptemp1);
3725 gfc_start_block (&body);
3726 gfc_init_se (&lse, NULL);
3727 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3728 gfc_init_se (&rse, NULL);
3729 rse.want_pointer = 1;
3730 gfc_conv_expr (&rse, expr2);
3731 gfc_add_block_to_block (&body, &rse.pre);
3732 gfc_add_modify (&body, lse.expr,
3733 fold_convert (TREE_TYPE (lse.expr), rse.expr));
3734 gfc_add_block_to_block (&body, &rse.post);
3735
3736 /* Increment count. */
3737 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3738 count, gfc_index_one_node);
3739 gfc_add_modify (&body, count, tmp);
3740
3741 tmp = gfc_finish_block (&body);
3742
3743 /* Generate body and loops according to the information in
3744 nested_forall_info. */
3745 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3746 gfc_add_expr_to_block (block, tmp);
3747
3748 /* Reset count. */
3749 gfc_add_modify (block, count, gfc_index_zero_node);
3750
3751 gfc_start_block (&body);
3752 gfc_init_se (&lse, NULL);
3753 gfc_init_se (&rse, NULL);
3754 rse.expr = gfc_build_array_ref (tmp1, count, NULL);
3755 lse.want_pointer = 1;
3756 gfc_conv_expr (&lse, expr1);
3757 gfc_add_block_to_block (&body, &lse.pre);
3758 gfc_add_modify (&body, lse.expr, rse.expr);
3759 gfc_add_block_to_block (&body, &lse.post);
3760 /* Increment count. */
3761 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3762 count, gfc_index_one_node);
3763 gfc_add_modify (&body, count, tmp);
3764 tmp = gfc_finish_block (&body);
3765
3766 /* Generate body and loops according to the information in
3767 nested_forall_info. */
3768 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3769 gfc_add_expr_to_block (block, tmp);
3770 }
3771 else
3772 {
3773 gfc_init_loopinfo (&loop);
3774
3775 /* Associate the SS with the loop. */
3776 gfc_add_ss_to_loop (&loop, rss);
3777
3778 /* Setup the scalarizing loops and bounds. */
3779 gfc_conv_ss_startstride (&loop);
3780
3781 gfc_conv_loop_setup (&loop, &expr2->where);
3782
3783 info = &rss->info->data.array;
3784 desc = info->descriptor;
3785
3786 /* Make a new descriptor. */
3787 parmtype = gfc_get_element_type (TREE_TYPE (desc));
3788 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen, 0,
3789 loop.from, loop.to, 1,
3790 GFC_ARRAY_UNKNOWN, true);
3791
3792 /* Allocate temporary for nested forall construct. */
3793 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
3794 inner_size, NULL, block, &ptemp1);
3795 gfc_start_block (&body);
3796 gfc_init_se (&lse, NULL);
3797 lse.expr = gfc_build_array_ref (tmp1, count, NULL);
3798 lse.direct_byref = 1;
3799 gfc_conv_expr_descriptor (&lse, expr2);
3800
3801 gfc_add_block_to_block (&body, &lse.pre);
3802 gfc_add_block_to_block (&body, &lse.post);
3803
3804 /* Increment count. */
3805 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3806 count, gfc_index_one_node);
3807 gfc_add_modify (&body, count, tmp);
3808
3809 tmp = gfc_finish_block (&body);
3810
3811 /* Generate body and loops according to the information in
3812 nested_forall_info. */
3813 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3814 gfc_add_expr_to_block (block, tmp);
3815
3816 /* Reset count. */
3817 gfc_add_modify (block, count, gfc_index_zero_node);
3818
3819 parm = gfc_build_array_ref (tmp1, count, NULL);
3820 gfc_init_se (&lse, NULL);
3821 gfc_conv_expr_descriptor (&lse, expr1);
3822 gfc_add_modify (&lse.pre, lse.expr, parm);
3823 gfc_start_block (&body);
3824 gfc_add_block_to_block (&body, &lse.pre);
3825 gfc_add_block_to_block (&body, &lse.post);
3826
3827 /* Increment count. */
3828 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
3829 count, gfc_index_one_node);
3830 gfc_add_modify (&body, count, tmp);
3831
3832 tmp = gfc_finish_block (&body);
3833
3834 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
3835 gfc_add_expr_to_block (block, tmp);
3836 }
3837 /* Free the temporary. */
3838 if (ptemp1)
3839 {
3840 tmp = gfc_call_free (ptemp1);
3841 gfc_add_expr_to_block (block, tmp);
3842 }
3843 }
3844
3845
3846 /* FORALL and WHERE statements are really nasty, especially when you nest
3847 them. All the rhs of a forall assignment must be evaluated before the
3848 actual assignments are performed. Presumably this also applies to all the
3849 assignments in an inner where statement. */
3850
3851 /* Generate code for a FORALL statement. Any temporaries are allocated as a
3852 linear array, relying on the fact that we process in the same order in all
3853 loops.
3854
3855 forall (i=start:end:stride; maskexpr)
3856 e<i> = f<i>
3857 g<i> = h<i>
3858 end forall
3859 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
3860 Translates to:
3861 count = ((end + 1 - start) / stride)
3862 masktmp(:) = maskexpr(:)
3863
3864 maskindex = 0;
3865 for (i = start; i <= end; i += stride)
3866 {
3867 if (masktmp[maskindex++])
3868 e<i> = f<i>
3869 }
3870 maskindex = 0;
3871 for (i = start; i <= end; i += stride)
3872 {
3873 if (masktmp[maskindex++])
3874 g<i> = h<i>
3875 }
3876
3877 Note that this code only works when there are no dependencies.
3878 Forall loop with array assignments and data dependencies are a real pain,
3879 because the size of the temporary cannot always be determined before the
3880 loop is executed. This problem is compounded by the presence of nested
3881 FORALL constructs.
3882 */
3883
3884 static tree
3885 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
3886 {
3887 stmtblock_t pre;
3888 stmtblock_t post;
3889 stmtblock_t block;
3890 stmtblock_t body;
3891 tree *var;
3892 tree *start;
3893 tree *end;
3894 tree *step;
3895 gfc_expr **varexpr;
3896 tree tmp;
3897 tree assign;
3898 tree size;
3899 tree maskindex;
3900 tree mask;
3901 tree pmask;
3902 tree cycle_label = NULL_TREE;
3903 int n;
3904 int nvar;
3905 int need_temp;
3906 gfc_forall_iterator *fa;
3907 gfc_se se;
3908 gfc_code *c;
3909 gfc_saved_var *saved_vars;
3910 iter_info *this_forall;
3911 forall_info *info;
3912 bool need_mask;
3913
3914 /* Do nothing if the mask is false. */
3915 if (code->expr1
3916 && code->expr1->expr_type == EXPR_CONSTANT
3917 && !code->expr1->value.logical)
3918 return build_empty_stmt (input_location);
3919
3920 n = 0;
3921 /* Count the FORALL index number. */
3922 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
3923 n++;
3924 nvar = n;
3925
3926 /* Allocate the space for var, start, end, step, varexpr. */
3927 var = XCNEWVEC (tree, nvar);
3928 start = XCNEWVEC (tree, nvar);
3929 end = XCNEWVEC (tree, nvar);
3930 step = XCNEWVEC (tree, nvar);
3931 varexpr = XCNEWVEC (gfc_expr *, nvar);
3932 saved_vars = XCNEWVEC (gfc_saved_var, nvar);
3933
3934 /* Allocate the space for info. */
3935 info = XCNEW (forall_info);
3936
3937 gfc_start_block (&pre);
3938 gfc_init_block (&post);
3939 gfc_init_block (&block);
3940
3941 n = 0;
3942 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
3943 {
3944 gfc_symbol *sym = fa->var->symtree->n.sym;
3945
3946 /* Allocate space for this_forall. */
3947 this_forall = XCNEW (iter_info);
3948
3949 /* Create a temporary variable for the FORALL index. */
3950 tmp = gfc_typenode_for_spec (&sym->ts);
3951 var[n] = gfc_create_var (tmp, sym->name);
3952 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
3953
3954 /* Record it in this_forall. */
3955 this_forall->var = var[n];
3956
3957 /* Replace the index symbol's backend_decl with the temporary decl. */
3958 sym->backend_decl = var[n];
3959
3960 /* Work out the start, end and stride for the loop. */
3961 gfc_init_se (&se, NULL);
3962 gfc_conv_expr_val (&se, fa->start);
3963 /* Record it in this_forall. */
3964 this_forall->start = se.expr;
3965 gfc_add_block_to_block (&block, &se.pre);
3966 start[n] = se.expr;
3967
3968 gfc_init_se (&se, NULL);
3969 gfc_conv_expr_val (&se, fa->end);
3970 /* Record it in this_forall. */
3971 this_forall->end = se.expr;
3972 gfc_make_safe_expr (&se);
3973 gfc_add_block_to_block (&block, &se.pre);
3974 end[n] = se.expr;
3975
3976 gfc_init_se (&se, NULL);
3977 gfc_conv_expr_val (&se, fa->stride);
3978 /* Record it in this_forall. */
3979 this_forall->step = se.expr;
3980 gfc_make_safe_expr (&se);
3981 gfc_add_block_to_block (&block, &se.pre);
3982 step[n] = se.expr;
3983
3984 /* Set the NEXT field of this_forall to NULL. */
3985 this_forall->next = NULL;
3986 /* Link this_forall to the info construct. */
3987 if (info->this_loop)
3988 {
3989 iter_info *iter_tmp = info->this_loop;
3990 while (iter_tmp->next != NULL)
3991 iter_tmp = iter_tmp->next;
3992 iter_tmp->next = this_forall;
3993 }
3994 else
3995 info->this_loop = this_forall;
3996
3997 n++;
3998 }
3999 nvar = n;
4000
4001 /* Calculate the size needed for the current forall level. */
4002 size = gfc_index_one_node;
4003 for (n = 0; n < nvar; n++)
4004 {
4005 /* size = (end + step - start) / step. */
4006 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (start[n]),
4007 step[n], start[n]);
4008 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (end[n]),
4009 end[n], tmp);
4010 tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, TREE_TYPE (tmp),
4011 tmp, step[n]);
4012 tmp = convert (gfc_array_index_type, tmp);
4013
4014 size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4015 size, tmp);
4016 }
4017
4018 /* Record the nvar and size of current forall level. */
4019 info->nvar = nvar;
4020 info->size = size;
4021
4022 if (code->expr1)
4023 {
4024 /* If the mask is .true., consider the FORALL unconditional. */
4025 if (code->expr1->expr_type == EXPR_CONSTANT
4026 && code->expr1->value.logical)
4027 need_mask = false;
4028 else
4029 need_mask = true;
4030 }
4031 else
4032 need_mask = false;
4033
4034 /* First we need to allocate the mask. */
4035 if (need_mask)
4036 {
4037 /* As the mask array can be very big, prefer compact boolean types. */
4038 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4039 mask = allocate_temp_for_forall_nest (nested_forall_info, mask_type,
4040 size, NULL, &block, &pmask);
4041 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
4042
4043 /* Record them in the info structure. */
4044 info->maskindex = maskindex;
4045 info->mask = mask;
4046 }
4047 else
4048 {
4049 /* No mask was specified. */
4050 maskindex = NULL_TREE;
4051 mask = pmask = NULL_TREE;
4052 }
4053
4054 /* Link the current forall level to nested_forall_info. */
4055 info->prev_nest = nested_forall_info;
4056 nested_forall_info = info;
4057
4058 /* Copy the mask into a temporary variable if required.
4059 For now we assume a mask temporary is needed. */
4060 if (need_mask)
4061 {
4062 /* As the mask array can be very big, prefer compact boolean types. */
4063 tree mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4064
4065 gfc_add_modify (&block, maskindex, gfc_index_zero_node);
4066
4067 /* Start of mask assignment loop body. */
4068 gfc_start_block (&body);
4069
4070 /* Evaluate the mask expression. */
4071 gfc_init_se (&se, NULL);
4072 gfc_conv_expr_val (&se, code->expr1);
4073 gfc_add_block_to_block (&body, &se.pre);
4074
4075 /* Store the mask. */
4076 se.expr = convert (mask_type, se.expr);
4077
4078 tmp = gfc_build_array_ref (mask, maskindex, NULL);
4079 gfc_add_modify (&body, tmp, se.expr);
4080
4081 /* Advance to the next mask element. */
4082 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4083 maskindex, gfc_index_one_node);
4084 gfc_add_modify (&body, maskindex, tmp);
4085
4086 /* Generate the loops. */
4087 tmp = gfc_finish_block (&body);
4088 tmp = gfc_trans_nested_forall_loop (info, tmp, 0);
4089 gfc_add_expr_to_block (&block, tmp);
4090 }
4091
4092 if (code->op == EXEC_DO_CONCURRENT)
4093 {
4094 gfc_init_block (&body);
4095 cycle_label = gfc_build_label_decl (NULL_TREE);
4096 code->cycle_label = cycle_label;
4097 tmp = gfc_trans_code (code->block->next);
4098 gfc_add_expr_to_block (&body, tmp);
4099
4100 if (TREE_USED (cycle_label))
4101 {
4102 tmp = build1_v (LABEL_EXPR, cycle_label);
4103 gfc_add_expr_to_block (&body, tmp);
4104 }
4105
4106 tmp = gfc_finish_block (&body);
4107 nested_forall_info->do_concurrent = true;
4108 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1);
4109 gfc_add_expr_to_block (&block, tmp);
4110 goto done;
4111 }
4112
4113 c = code->block->next;
4114
4115 /* TODO: loop merging in FORALL statements. */
4116 /* Now that we've got a copy of the mask, generate the assignment loops. */
4117 while (c)
4118 {
4119 switch (c->op)
4120 {
4121 case EXEC_ASSIGN:
4122 /* A scalar or array assignment. DO the simple check for
4123 lhs to rhs dependencies. These make a temporary for the
4124 rhs and form a second forall block to copy to variable. */
4125 need_temp = check_forall_dependencies(c, &pre, &post);
4126
4127 /* Temporaries due to array assignment data dependencies introduce
4128 no end of problems. */
4129 if (need_temp)
4130 gfc_trans_assign_need_temp (c->expr1, c->expr2, NULL, false,
4131 nested_forall_info, &block);
4132 else
4133 {
4134 /* Use the normal assignment copying routines. */
4135 assign = gfc_trans_assignment (c->expr1, c->expr2, false, true);
4136
4137 /* Generate body and loops. */
4138 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4139 assign, 1);
4140 gfc_add_expr_to_block (&block, tmp);
4141 }
4142
4143 /* Cleanup any temporary symtrees that have been made to deal
4144 with dependencies. */
4145 if (new_symtree)
4146 cleanup_forall_symtrees (c);
4147
4148 break;
4149
4150 case EXEC_WHERE:
4151 /* Translate WHERE or WHERE construct nested in FORALL. */
4152 gfc_trans_where_2 (c, NULL, false, nested_forall_info, &block);
4153 break;
4154
4155 /* Pointer assignment inside FORALL. */
4156 case EXEC_POINTER_ASSIGN:
4157 need_temp = gfc_check_dependency (c->expr1, c->expr2, 0);
4158 if (need_temp)
4159 gfc_trans_pointer_assign_need_temp (c->expr1, c->expr2,
4160 nested_forall_info, &block);
4161 else
4162 {
4163 /* Use the normal assignment copying routines. */
4164 assign = gfc_trans_pointer_assignment (c->expr1, c->expr2);
4165
4166 /* Generate body and loops. */
4167 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4168 assign, 1);
4169 gfc_add_expr_to_block (&block, tmp);
4170 }
4171 break;
4172
4173 case EXEC_FORALL:
4174 tmp = gfc_trans_forall_1 (c, nested_forall_info);
4175 gfc_add_expr_to_block (&block, tmp);
4176 break;
4177
4178 /* Explicit subroutine calls are prevented by the frontend but interface
4179 assignments can legitimately produce them. */
4180 case EXEC_ASSIGN_CALL:
4181 assign = gfc_trans_call (c, true, NULL_TREE, NULL_TREE, false);
4182 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1);
4183 gfc_add_expr_to_block (&block, tmp);
4184 break;
4185
4186 default:
4187 gcc_unreachable ();
4188 }
4189
4190 c = c->next;
4191 }
4192
4193 done:
4194 /* Restore the original index variables. */
4195 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
4196 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
4197
4198 /* Free the space for var, start, end, step, varexpr. */
4199 free (var);
4200 free (start);
4201 free (end);
4202 free (step);
4203 free (varexpr);
4204 free (saved_vars);
4205
4206 for (this_forall = info->this_loop; this_forall;)
4207 {
4208 iter_info *next = this_forall->next;
4209 free (this_forall);
4210 this_forall = next;
4211 }
4212
4213 /* Free the space for this forall_info. */
4214 free (info);
4215
4216 if (pmask)
4217 {
4218 /* Free the temporary for the mask. */
4219 tmp = gfc_call_free (pmask);
4220 gfc_add_expr_to_block (&block, tmp);
4221 }
4222 if (maskindex)
4223 pushdecl (maskindex);
4224
4225 gfc_add_block_to_block (&pre, &block);
4226 gfc_add_block_to_block (&pre, &post);
4227
4228 return gfc_finish_block (&pre);
4229 }
4230
4231
4232 /* Translate the FORALL statement or construct. */
4233
4234 tree gfc_trans_forall (gfc_code * code)
4235 {
4236 return gfc_trans_forall_1 (code, NULL);
4237 }
4238
4239
4240 /* Translate the DO CONCURRENT construct. */
4241
4242 tree gfc_trans_do_concurrent (gfc_code * code)
4243 {
4244 return gfc_trans_forall_1 (code, NULL);
4245 }
4246
4247
4248 /* Evaluate the WHERE mask expression, copy its value to a temporary.
4249 If the WHERE construct is nested in FORALL, compute the overall temporary
4250 needed by the WHERE mask expression multiplied by the iterator number of
4251 the nested forall.
4252 ME is the WHERE mask expression.
4253 MASK is the current execution mask upon input, whose sense may or may
4254 not be inverted as specified by the INVERT argument.
4255 CMASK is the updated execution mask on output, or NULL if not required.
4256 PMASK is the pending execution mask on output, or NULL if not required.
4257 BLOCK is the block in which to place the condition evaluation loops. */
4258
4259 static void
4260 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
4261 tree mask, bool invert, tree cmask, tree pmask,
4262 tree mask_type, stmtblock_t * block)
4263 {
4264 tree tmp, tmp1;
4265 gfc_ss *lss, *rss;
4266 gfc_loopinfo loop;
4267 stmtblock_t body, body1;
4268 tree count, cond, mtmp;
4269 gfc_se lse, rse;
4270
4271 gfc_init_loopinfo (&loop);
4272
4273 lss = gfc_walk_expr (me);
4274 rss = gfc_walk_expr (me);
4275
4276 /* Variable to index the temporary. */
4277 count = gfc_create_var (gfc_array_index_type, "count");
4278 /* Initialize count. */
4279 gfc_add_modify (block, count, gfc_index_zero_node);
4280
4281 gfc_start_block (&body);
4282
4283 gfc_init_se (&rse, NULL);
4284 gfc_init_se (&lse, NULL);
4285
4286 if (lss == gfc_ss_terminator)
4287 {
4288 gfc_init_block (&body1);
4289 }
4290 else
4291 {
4292 /* Initialize the loop. */
4293 gfc_init_loopinfo (&loop);
4294
4295 /* We may need LSS to determine the shape of the expression. */
4296 gfc_add_ss_to_loop (&loop, lss);
4297 gfc_add_ss_to_loop (&loop, rss);
4298
4299 gfc_conv_ss_startstride (&loop);
4300 gfc_conv_loop_setup (&loop, &me->where);
4301
4302 gfc_mark_ss_chain_used (rss, 1);
4303 /* Start the loop body. */
4304 gfc_start_scalarized_body (&loop, &body1);
4305
4306 /* Translate the expression. */
4307 gfc_copy_loopinfo_to_se (&rse, &loop);
4308 rse.ss = rss;
4309 gfc_conv_expr (&rse, me);
4310 }
4311
4312 /* Variable to evaluate mask condition. */
4313 cond = gfc_create_var (mask_type, "cond");
4314 if (mask && (cmask || pmask))
4315 mtmp = gfc_create_var (mask_type, "mask");
4316 else mtmp = NULL_TREE;
4317
4318 gfc_add_block_to_block (&body1, &lse.pre);
4319 gfc_add_block_to_block (&body1, &rse.pre);
4320
4321 gfc_add_modify (&body1, cond, fold_convert (mask_type, rse.expr));
4322
4323 if (mask && (cmask || pmask))
4324 {
4325 tmp = gfc_build_array_ref (mask, count, NULL);
4326 if (invert)
4327 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, tmp);
4328 gfc_add_modify (&body1, mtmp, tmp);
4329 }
4330
4331 if (cmask)
4332 {
4333 tmp1 = gfc_build_array_ref (cmask, count, NULL);
4334 tmp = cond;
4335 if (mask)
4336 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type,
4337 mtmp, tmp);
4338 gfc_add_modify (&body1, tmp1, tmp);
4339 }
4340
4341 if (pmask)
4342 {
4343 tmp1 = gfc_build_array_ref (pmask, count, NULL);
4344 tmp = fold_build1_loc (input_location, TRUTH_NOT_EXPR, mask_type, cond);
4345 if (mask)
4346 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, mask_type, mtmp,
4347 tmp);
4348 gfc_add_modify (&body1, tmp1, tmp);
4349 }
4350
4351 gfc_add_block_to_block (&body1, &lse.post);
4352 gfc_add_block_to_block (&body1, &rse.post);
4353
4354 if (lss == gfc_ss_terminator)
4355 {
4356 gfc_add_block_to_block (&body, &body1);
4357 }
4358 else
4359 {
4360 /* Increment count. */
4361 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4362 count, gfc_index_one_node);
4363 gfc_add_modify (&body1, count, tmp1);
4364
4365 /* Generate the copying loops. */
4366 gfc_trans_scalarizing_loops (&loop, &body1);
4367
4368 gfc_add_block_to_block (&body, &loop.pre);
4369 gfc_add_block_to_block (&body, &loop.post);
4370
4371 gfc_cleanup_loop (&loop);
4372 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
4373 as tree nodes in SS may not be valid in different scope. */
4374 }
4375
4376 tmp1 = gfc_finish_block (&body);
4377 /* If the WHERE construct is inside FORALL, fill the full temporary. */
4378 if (nested_forall_info != NULL)
4379 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1);
4380
4381 gfc_add_expr_to_block (block, tmp1);
4382 }
4383
4384
4385 /* Translate an assignment statement in a WHERE statement or construct
4386 statement. The MASK expression is used to control which elements
4387 of EXPR1 shall be assigned. The sense of MASK is specified by
4388 INVERT. */
4389
4390 static tree
4391 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2,
4392 tree mask, bool invert,
4393 tree count1, tree count2,
4394 gfc_code *cnext)
4395 {
4396 gfc_se lse;
4397 gfc_se rse;
4398 gfc_ss *lss;
4399 gfc_ss *lss_section;
4400 gfc_ss *rss;
4401
4402 gfc_loopinfo loop;
4403 tree tmp;
4404 stmtblock_t block;
4405 stmtblock_t body;
4406 tree index, maskexpr;
4407
4408 /* A defined assignment. */
4409 if (cnext && cnext->resolved_sym)
4410 return gfc_trans_call (cnext, true, mask, count1, invert);
4411
4412 #if 0
4413 /* TODO: handle this special case.
4414 Special case a single function returning an array. */
4415 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
4416 {
4417 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
4418 if (tmp)
4419 return tmp;
4420 }
4421 #endif
4422
4423 /* Assignment of the form lhs = rhs. */
4424 gfc_start_block (&block);
4425
4426 gfc_init_se (&lse, NULL);
4427 gfc_init_se (&rse, NULL);
4428
4429 /* Walk the lhs. */
4430 lss = gfc_walk_expr (expr1);
4431 rss = NULL;
4432
4433 /* In each where-assign-stmt, the mask-expr and the variable being
4434 defined shall be arrays of the same shape. */
4435 gcc_assert (lss != gfc_ss_terminator);
4436
4437 /* The assignment needs scalarization. */
4438 lss_section = lss;
4439
4440 /* Find a non-scalar SS from the lhs. */
4441 while (lss_section != gfc_ss_terminator
4442 && lss_section->info->type != GFC_SS_SECTION)
4443 lss_section = lss_section->next;
4444
4445 gcc_assert (lss_section != gfc_ss_terminator);
4446
4447 /* Initialize the scalarizer. */
4448 gfc_init_loopinfo (&loop);
4449
4450 /* Walk the rhs. */
4451 rss = gfc_walk_expr (expr2);
4452 if (rss == gfc_ss_terminator)
4453 {
4454 /* The rhs is scalar. Add a ss for the expression. */
4455 rss = gfc_get_scalar_ss (gfc_ss_terminator, expr2);
4456 rss->info->where = 1;
4457 }
4458
4459 /* Associate the SS with the loop. */
4460 gfc_add_ss_to_loop (&loop, lss);
4461 gfc_add_ss_to_loop (&loop, rss);
4462
4463 /* Calculate the bounds of the scalarization. */
4464 gfc_conv_ss_startstride (&loop);
4465
4466 /* Resolve any data dependencies in the statement. */
4467 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
4468
4469 /* Setup the scalarizing loops. */
4470 gfc_conv_loop_setup (&loop, &expr2->where);
4471
4472 /* Setup the gfc_se structures. */
4473 gfc_copy_loopinfo_to_se (&lse, &loop);
4474 gfc_copy_loopinfo_to_se (&rse, &loop);
4475
4476 rse.ss = rss;
4477 gfc_mark_ss_chain_used (rss, 1);
4478 if (loop.temp_ss == NULL)
4479 {
4480 lse.ss = lss;
4481 gfc_mark_ss_chain_used (lss, 1);
4482 }
4483 else
4484 {
4485 lse.ss = loop.temp_ss;
4486 gfc_mark_ss_chain_used (lss, 3);
4487 gfc_mark_ss_chain_used (loop.temp_ss, 3);
4488 }
4489
4490 /* Start the scalarized loop body. */
4491 gfc_start_scalarized_body (&loop, &body);
4492
4493 /* Translate the expression. */
4494 gfc_conv_expr (&rse, expr2);
4495 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
4496 gfc_conv_tmp_array_ref (&lse);
4497 else
4498 gfc_conv_expr (&lse, expr1);
4499
4500 /* Form the mask expression according to the mask. */
4501 index = count1;
4502 maskexpr = gfc_build_array_ref (mask, index, NULL);
4503 if (invert)
4504 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4505 TREE_TYPE (maskexpr), maskexpr);
4506
4507 /* Use the scalar assignment as is. */
4508 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts,
4509 loop.temp_ss != NULL, false, true);
4510
4511 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt (input_location));
4512
4513 gfc_add_expr_to_block (&body, tmp);
4514
4515 if (lss == gfc_ss_terminator)
4516 {
4517 /* Increment count1. */
4518 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
4519 count1, gfc_index_one_node);
4520 gfc_add_modify (&body, count1, tmp);
4521
4522 /* Use the scalar assignment as is. */
4523 gfc_add_block_to_block (&block, &body);
4524 }
4525 else
4526 {
4527 gcc_assert (lse.ss == gfc_ss_terminator
4528 && rse.ss == gfc_ss_terminator);
4529
4530 if (loop.temp_ss != NULL)
4531 {
4532 /* Increment count1 before finish the main body of a scalarized
4533 expression. */
4534 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4535 gfc_array_index_type, count1, gfc_index_one_node);
4536 gfc_add_modify (&body, count1, tmp);
4537 gfc_trans_scalarized_loop_boundary (&loop, &body);
4538
4539 /* We need to copy the temporary to the actual lhs. */
4540 gfc_init_se (&lse, NULL);
4541 gfc_init_se (&rse, NULL);
4542 gfc_copy_loopinfo_to_se (&lse, &loop);
4543 gfc_copy_loopinfo_to_se (&rse, &loop);
4544
4545 rse.ss = loop.temp_ss;
4546 lse.ss = lss;
4547
4548 gfc_conv_tmp_array_ref (&rse);
4549 gfc_conv_expr (&lse, expr1);
4550
4551 gcc_assert (lse.ss == gfc_ss_terminator
4552 && rse.ss == gfc_ss_terminator);
4553
4554 /* Form the mask expression according to the mask tree list. */
4555 index = count2;
4556 maskexpr = gfc_build_array_ref (mask, index, NULL);
4557 if (invert)
4558 maskexpr = fold_build1_loc (input_location, TRUTH_NOT_EXPR,
4559 TREE_TYPE (maskexpr), maskexpr);
4560
4561 /* Use the scalar assignment as is. */
4562 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts, false, false,
4563 true);
4564 tmp = build3_v (COND_EXPR, maskexpr, tmp,
4565 build_empty_stmt (input_location));
4566 gfc_add_expr_to_block (&body, tmp);
4567
4568 /* Increment count2. */
4569 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4570 gfc_array_index_type, count2,
4571 gfc_index_one_node);
4572 gfc_add_modify (&body, count2, tmp);
4573 }
4574 else
4575 {
4576 /* Increment count1. */
4577 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4578 gfc_array_index_type, count1,
4579 gfc_index_one_node);
4580 gfc_add_modify (&body, count1, tmp);
4581 }
4582
4583 /* Generate the copying loops. */
4584 gfc_trans_scalarizing_loops (&loop, &body);
4585
4586 /* Wrap the whole thing up. */
4587 gfc_add_block_to_block (&block, &loop.pre);
4588 gfc_add_block_to_block (&block, &loop.post);
4589 gfc_cleanup_loop (&loop);
4590 }
4591
4592 return gfc_finish_block (&block);
4593 }
4594
4595
4596 /* Translate the WHERE construct or statement.
4597 This function can be called iteratively to translate the nested WHERE
4598 construct or statement.
4599 MASK is the control mask. */
4600
4601 static void
4602 gfc_trans_where_2 (gfc_code * code, tree mask, bool invert,
4603 forall_info * nested_forall_info, stmtblock_t * block)
4604 {
4605 stmtblock_t inner_size_body;
4606 tree inner_size, size;
4607 gfc_ss *lss, *rss;
4608 tree mask_type;
4609 gfc_expr *expr1;
4610 gfc_expr *expr2;
4611 gfc_code *cblock;
4612 gfc_code *cnext;
4613 tree tmp;
4614 tree cond;
4615 tree count1, count2;
4616 bool need_cmask;
4617 bool need_pmask;
4618 int need_temp;
4619 tree pcmask = NULL_TREE;
4620 tree ppmask = NULL_TREE;
4621 tree cmask = NULL_TREE;
4622 tree pmask = NULL_TREE;
4623 gfc_actual_arglist *arg;
4624
4625 /* the WHERE statement or the WHERE construct statement. */
4626 cblock = code->block;
4627
4628 /* As the mask array can be very big, prefer compact boolean types. */
4629 mask_type = gfc_get_logical_type (gfc_logical_kinds[0].kind);
4630
4631 /* Determine which temporary masks are needed. */
4632 if (!cblock->block)
4633 {
4634 /* One clause: No ELSEWHEREs. */
4635 need_cmask = (cblock->next != 0);
4636 need_pmask = false;
4637 }
4638 else if (cblock->block->block)
4639 {
4640 /* Three or more clauses: Conditional ELSEWHEREs. */
4641 need_cmask = true;
4642 need_pmask = true;
4643 }
4644 else if (cblock->next)
4645 {
4646 /* Two clauses, the first non-empty. */
4647 need_cmask = true;
4648 need_pmask = (mask != NULL_TREE
4649 && cblock->block->next != 0);
4650 }
4651 else if (!cblock->block->next)
4652 {
4653 /* Two clauses, both empty. */
4654 need_cmask = false;
4655 need_pmask = false;
4656 }
4657 /* Two clauses, the first empty, the second non-empty. */
4658 else if (mask)
4659 {
4660 need_cmask = (cblock->block->expr1 != 0);
4661 need_pmask = true;
4662 }
4663 else
4664 {
4665 need_cmask = true;
4666 need_pmask = false;
4667 }
4668
4669 if (need_cmask || need_pmask)
4670 {
4671 /* Calculate the size of temporary needed by the mask-expr. */
4672 gfc_init_block (&inner_size_body);
4673 inner_size = compute_inner_temp_size (cblock->expr1, cblock->expr1,
4674 &inner_size_body, &lss, &rss);
4675
4676 gfc_free_ss_chain (lss);
4677 gfc_free_ss_chain (rss);
4678
4679 /* Calculate the total size of temporary needed. */
4680 size = compute_overall_iter_number (nested_forall_info, inner_size,
4681 &inner_size_body, block);
4682
4683 /* Check whether the size is negative. */
4684 cond = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, size,
4685 gfc_index_zero_node);
4686 size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type,
4687 cond, gfc_index_zero_node, size);
4688 size = gfc_evaluate_now (size, block);
4689
4690 /* Allocate temporary for WHERE mask if needed. */
4691 if (need_cmask)
4692 cmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4693 &pcmask);
4694
4695 /* Allocate temporary for !mask if needed. */
4696 if (need_pmask)
4697 pmask = allocate_temp_for_forall_nest_1 (mask_type, size, block,
4698 &ppmask);
4699 }
4700
4701 while (cblock)
4702 {
4703 /* Each time around this loop, the where clause is conditional
4704 on the value of mask and invert, which are updated at the
4705 bottom of the loop. */
4706
4707 /* Has mask-expr. */
4708 if (cblock->expr1)
4709 {
4710 /* Ensure that the WHERE mask will be evaluated exactly once.
4711 If there are no statements in this WHERE/ELSEWHERE clause,
4712 then we don't need to update the control mask (cmask).
4713 If this is the last clause of the WHERE construct, then
4714 we don't need to update the pending control mask (pmask). */
4715 if (mask)
4716 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4717 mask, invert,
4718 cblock->next ? cmask : NULL_TREE,
4719 cblock->block ? pmask : NULL_TREE,
4720 mask_type, block);
4721 else
4722 gfc_evaluate_where_mask (cblock->expr1, nested_forall_info,
4723 NULL_TREE, false,
4724 (cblock->next || cblock->block)
4725 ? cmask : NULL_TREE,
4726 NULL_TREE, mask_type, block);
4727
4728 invert = false;
4729 }
4730 /* It's a final elsewhere-stmt. No mask-expr is present. */
4731 else
4732 cmask = mask;
4733
4734 /* The body of this where clause are controlled by cmask with
4735 sense specified by invert. */
4736
4737 /* Get the assignment statement of a WHERE statement, or the first
4738 statement in where-body-construct of a WHERE construct. */
4739 cnext = cblock->next;
4740 while (cnext)
4741 {
4742 switch (cnext->op)
4743 {
4744 /* WHERE assignment statement. */
4745 case EXEC_ASSIGN_CALL:
4746
4747 arg = cnext->ext.actual;
4748 expr1 = expr2 = NULL;
4749 for (; arg; arg = arg->next)
4750 {
4751 if (!arg->expr)
4752 continue;
4753 if (expr1 == NULL)
4754 expr1 = arg->expr;
4755 else
4756 expr2 = arg->expr;
4757 }
4758 goto evaluate;
4759
4760 case EXEC_ASSIGN:
4761 expr1 = cnext->expr1;
4762 expr2 = cnext->expr2;
4763 evaluate:
4764 if (nested_forall_info != NULL)
4765 {
4766 need_temp = gfc_check_dependency (expr1, expr2, 0);
4767 if (need_temp && cnext->op != EXEC_ASSIGN_CALL)
4768 gfc_trans_assign_need_temp (expr1, expr2,
4769 cmask, invert,
4770 nested_forall_info, block);
4771 else
4772 {
4773 /* Variables to control maskexpr. */
4774 count1 = gfc_create_var (gfc_array_index_type, "count1");
4775 count2 = gfc_create_var (gfc_array_index_type, "count2");
4776 gfc_add_modify (block, count1, gfc_index_zero_node);
4777 gfc_add_modify (block, count2, gfc_index_zero_node);
4778
4779 tmp = gfc_trans_where_assign (expr1, expr2,
4780 cmask, invert,
4781 count1, count2,
4782 cnext);
4783
4784 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
4785 tmp, 1);
4786 gfc_add_expr_to_block (block, tmp);
4787 }
4788 }
4789 else
4790 {
4791 /* Variables to control maskexpr. */
4792 count1 = gfc_create_var (gfc_array_index_type, "count1");
4793 count2 = gfc_create_var (gfc_array_index_type, "count2");
4794 gfc_add_modify (block, count1, gfc_index_zero_node);
4795 gfc_add_modify (block, count2, gfc_index_zero_node);
4796
4797 tmp = gfc_trans_where_assign (expr1, expr2,
4798 cmask, invert,
4799 count1, count2,
4800 cnext);
4801 gfc_add_expr_to_block (block, tmp);
4802
4803 }
4804 break;
4805
4806 /* WHERE or WHERE construct is part of a where-body-construct. */
4807 case EXEC_WHERE:
4808 gfc_trans_where_2 (cnext, cmask, invert,
4809 nested_forall_info, block);
4810 break;
4811
4812 default:
4813 gcc_unreachable ();
4814 }
4815
4816 /* The next statement within the same where-body-construct. */
4817 cnext = cnext->next;
4818 }
4819 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
4820 cblock = cblock->block;
4821 if (mask == NULL_TREE)
4822 {
4823 /* If we're the initial WHERE, we can simply invert the sense
4824 of the current mask to obtain the "mask" for the remaining
4825 ELSEWHEREs. */
4826 invert = true;
4827 mask = cmask;
4828 }
4829 else
4830 {
4831 /* Otherwise, for nested WHERE's we need to use the pending mask. */
4832 invert = false;
4833 mask = pmask;
4834 }
4835 }
4836
4837 /* If we allocated a pending mask array, deallocate it now. */
4838 if (ppmask)
4839 {
4840 tmp = gfc_call_free (ppmask);
4841 gfc_add_expr_to_block (block, tmp);
4842 }
4843
4844 /* If we allocated a current mask array, deallocate it now. */
4845 if (pcmask)
4846 {
4847 tmp = gfc_call_free (pcmask);
4848 gfc_add_expr_to_block (block, tmp);
4849 }
4850 }
4851
4852 /* Translate a simple WHERE construct or statement without dependencies.
4853 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
4854 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
4855 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
4856
4857 static tree
4858 gfc_trans_where_3 (gfc_code * cblock, gfc_code * eblock)
4859 {
4860 stmtblock_t block, body;
4861 gfc_expr *cond, *tdst, *tsrc, *edst, *esrc;
4862 tree tmp, cexpr, tstmt, estmt;
4863 gfc_ss *css, *tdss, *tsss;
4864 gfc_se cse, tdse, tsse, edse, esse;
4865 gfc_loopinfo loop;
4866 gfc_ss *edss = 0;
4867 gfc_ss *esss = 0;
4868
4869 /* Allow the scalarizer to workshare simple where loops. */
4870 if (ompws_flags & OMPWS_WORKSHARE_FLAG)
4871 ompws_flags |= OMPWS_SCALARIZER_WS;
4872
4873 cond = cblock->expr1;
4874 tdst = cblock->next->expr1;
4875 tsrc = cblock->next->expr2;
4876 edst = eblock ? eblock->next->expr1 : NULL;
4877 esrc = eblock ? eblock->next->expr2 : NULL;
4878
4879 gfc_start_block (&block);
4880 gfc_init_loopinfo (&loop);
4881
4882 /* Handle the condition. */
4883 gfc_init_se (&cse, NULL);
4884 css = gfc_walk_expr (cond);
4885 gfc_add_ss_to_loop (&loop, css);
4886
4887 /* Handle the then-clause. */
4888 gfc_init_se (&tdse, NULL);
4889 gfc_init_se (&tsse, NULL);
4890 tdss = gfc_walk_expr (tdst);
4891 tsss = gfc_walk_expr (tsrc);
4892 if (tsss == gfc_ss_terminator)
4893 {
4894 tsss = gfc_get_scalar_ss (gfc_ss_terminator, tsrc);
4895 tsss->info->where = 1;
4896 }
4897 gfc_add_ss_to_loop (&loop, tdss);
4898 gfc_add_ss_to_loop (&loop, tsss);
4899
4900 if (eblock)
4901 {
4902 /* Handle the else clause. */
4903 gfc_init_se (&edse, NULL);
4904 gfc_init_se (&esse, NULL);
4905 edss = gfc_walk_expr (edst);
4906 esss = gfc_walk_expr (esrc);
4907 if (esss == gfc_ss_terminator)
4908 {
4909 esss = gfc_get_scalar_ss (gfc_ss_terminator, esrc);
4910 esss->info->where = 1;
4911 }
4912 gfc_add_ss_to_loop (&loop, edss);
4913 gfc_add_ss_to_loop (&loop, esss);
4914 }
4915
4916 gfc_conv_ss_startstride (&loop);
4917 gfc_conv_loop_setup (&loop, &tdst->where);
4918
4919 gfc_mark_ss_chain_used (css, 1);
4920 gfc_mark_ss_chain_used (tdss, 1);
4921 gfc_mark_ss_chain_used (tsss, 1);
4922 if (eblock)
4923 {
4924 gfc_mark_ss_chain_used (edss, 1);
4925 gfc_mark_ss_chain_used (esss, 1);
4926 }
4927
4928 gfc_start_scalarized_body (&loop, &body);
4929
4930 gfc_copy_loopinfo_to_se (&cse, &loop);
4931 gfc_copy_loopinfo_to_se (&tdse, &loop);
4932 gfc_copy_loopinfo_to_se (&tsse, &loop);
4933 cse.ss = css;
4934 tdse.ss = tdss;
4935 tsse.ss = tsss;
4936 if (eblock)
4937 {
4938 gfc_copy_loopinfo_to_se (&edse, &loop);
4939 gfc_copy_loopinfo_to_se (&esse, &loop);
4940 edse.ss = edss;
4941 esse.ss = esss;
4942 }
4943
4944 gfc_conv_expr (&cse, cond);
4945 gfc_add_block_to_block (&body, &cse.pre);
4946 cexpr = cse.expr;
4947
4948 gfc_conv_expr (&tsse, tsrc);
4949 if (tdss != gfc_ss_terminator && loop.temp_ss != NULL)
4950 gfc_conv_tmp_array_ref (&tdse);
4951 else
4952 gfc_conv_expr (&tdse, tdst);
4953
4954 if (eblock)
4955 {
4956 gfc_conv_expr (&esse, esrc);
4957 if (edss != gfc_ss_terminator && loop.temp_ss != NULL)
4958 gfc_conv_tmp_array_ref (&edse);
4959 else
4960 gfc_conv_expr (&edse, edst);
4961 }
4962
4963 tstmt = gfc_trans_scalar_assign (&tdse, &tsse, tdst->ts, false, false, true);
4964 estmt = eblock ? gfc_trans_scalar_assign (&edse, &esse, edst->ts, false,
4965 false, true)
4966 : build_empty_stmt (input_location);
4967 tmp = build3_v (COND_EXPR, cexpr, tstmt, estmt);
4968 gfc_add_expr_to_block (&body, tmp);
4969 gfc_add_block_to_block (&body, &cse.post);
4970
4971 gfc_trans_scalarizing_loops (&loop, &body);
4972 gfc_add_block_to_block (&block, &loop.pre);
4973 gfc_add_block_to_block (&block, &loop.post);
4974 gfc_cleanup_loop (&loop);
4975
4976 return gfc_finish_block (&block);
4977 }
4978
4979 /* As the WHERE or WHERE construct statement can be nested, we call
4980 gfc_trans_where_2 to do the translation, and pass the initial
4981 NULL values for both the control mask and the pending control mask. */
4982
4983 tree
4984 gfc_trans_where (gfc_code * code)
4985 {
4986 stmtblock_t block;
4987 gfc_code *cblock;
4988 gfc_code *eblock;
4989
4990 cblock = code->block;
4991 if (cblock->next
4992 && cblock->next->op == EXEC_ASSIGN
4993 && !cblock->next->next)
4994 {
4995 eblock = cblock->block;
4996 if (!eblock)
4997 {
4998 /* A simple "WHERE (cond) x = y" statement or block is
4999 dependence free if cond is not dependent upon writing x,
5000 and the source y is unaffected by the destination x. */
5001 if (!gfc_check_dependency (cblock->next->expr1,
5002 cblock->expr1, 0)
5003 && !gfc_check_dependency (cblock->next->expr1,
5004 cblock->next->expr2, 0))
5005 return gfc_trans_where_3 (cblock, NULL);
5006 }
5007 else if (!eblock->expr1
5008 && !eblock->block
5009 && eblock->next
5010 && eblock->next->op == EXEC_ASSIGN
5011 && !eblock->next->next)
5012 {
5013 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
5014 block is dependence free if cond is not dependent on writes
5015 to x1 and x2, y1 is not dependent on writes to x2, and y2
5016 is not dependent on writes to x1, and both y's are not
5017 dependent upon their own x's. In addition to this, the
5018 final two dependency checks below exclude all but the same
5019 array reference if the where and elswhere destinations
5020 are the same. In short, this is VERY conservative and this
5021 is needed because the two loops, required by the standard
5022 are coalesced in gfc_trans_where_3. */
5023 if (!gfc_check_dependency (cblock->next->expr1,
5024 cblock->expr1, 0)
5025 && !gfc_check_dependency (eblock->next->expr1,
5026 cblock->expr1, 0)
5027 && !gfc_check_dependency (cblock->next->expr1,
5028 eblock->next->expr2, 1)
5029 && !gfc_check_dependency (eblock->next->expr1,
5030 cblock->next->expr2, 1)
5031 && !gfc_check_dependency (cblock->next->expr1,
5032 cblock->next->expr2, 1)
5033 && !gfc_check_dependency (eblock->next->expr1,
5034 eblock->next->expr2, 1)
5035 && !gfc_check_dependency (cblock->next->expr1,
5036 eblock->next->expr1, 0)
5037 && !gfc_check_dependency (eblock->next->expr1,
5038 cblock->next->expr1, 0))
5039 return gfc_trans_where_3 (cblock, eblock);
5040 }
5041 }
5042
5043 gfc_start_block (&block);
5044
5045 gfc_trans_where_2 (code, NULL, false, NULL, &block);
5046
5047 return gfc_finish_block (&block);
5048 }
5049
5050
5051 /* CYCLE a DO loop. The label decl has already been created by
5052 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
5053 node at the head of the loop. We must mark the label as used. */
5054
5055 tree
5056 gfc_trans_cycle (gfc_code * code)
5057 {
5058 tree cycle_label;
5059
5060 cycle_label = code->ext.which_construct->cycle_label;
5061 gcc_assert (cycle_label);
5062
5063 TREE_USED (cycle_label) = 1;
5064 return build1_v (GOTO_EXPR, cycle_label);
5065 }
5066
5067
5068 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
5069 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
5070 loop. */
5071
5072 tree
5073 gfc_trans_exit (gfc_code * code)
5074 {
5075 tree exit_label;
5076
5077 exit_label = code->ext.which_construct->exit_label;
5078 gcc_assert (exit_label);
5079
5080 TREE_USED (exit_label) = 1;
5081 return build1_v (GOTO_EXPR, exit_label);
5082 }
5083
5084
5085 /* Translate the ALLOCATE statement. */
5086
5087 tree
5088 gfc_trans_allocate (gfc_code * code)
5089 {
5090 gfc_alloc *al;
5091 gfc_expr *expr;
5092 gfc_se se, se_sz;
5093 tree tmp;
5094 tree parm;
5095 tree stat;
5096 tree errmsg;
5097 tree errlen;
5098 tree label_errmsg;
5099 tree label_finish;
5100 tree memsz;
5101 tree al_vptr, al_len;
5102 /* If an expr3 is present, then store the tree for accessing its
5103 _vptr, and _len components in the variables, respectively. The
5104 element size, i.e. _vptr%size, is stored in expr3_esize. Any of
5105 the trees may be the NULL_TREE indicating that this is not
5106 available for expr3's type. */
5107 tree expr3, expr3_vptr, expr3_len, expr3_esize;
5108 stmtblock_t block;
5109 stmtblock_t post;
5110 tree nelems;
5111 bool upoly_expr, tmp_expr3_len_flag = false, al_len_needs_set;
5112
5113 if (!code->ext.alloc.list)
5114 return NULL_TREE;
5115
5116 stat = tmp = memsz = al_vptr = al_len = NULL_TREE;
5117 expr3 = expr3_vptr = expr3_len = expr3_esize = NULL_TREE;
5118 label_errmsg = label_finish = errmsg = errlen = NULL_TREE;
5119
5120 gfc_init_block (&block);
5121 gfc_init_block (&post);
5122
5123 /* STAT= (and maybe ERRMSG=) is present. */
5124 if (code->expr1)
5125 {
5126 /* STAT=. */
5127 tree gfc_int4_type_node = gfc_get_int_type (4);
5128 stat = gfc_create_var (gfc_int4_type_node, "stat");
5129
5130 /* ERRMSG= only makes sense with STAT=. */
5131 if (code->expr2)
5132 {
5133 gfc_init_se (&se, NULL);
5134 se.want_pointer = 1;
5135 gfc_conv_expr_lhs (&se, code->expr2);
5136 errmsg = se.expr;
5137 errlen = se.string_length;
5138 }
5139 else
5140 {
5141 errmsg = null_pointer_node;
5142 errlen = build_int_cst (gfc_charlen_type_node, 0);
5143 }
5144
5145 /* GOTO destinations. */
5146 label_errmsg = gfc_build_label_decl (NULL_TREE);
5147 label_finish = gfc_build_label_decl (NULL_TREE);
5148 TREE_USED (label_finish) = 0;
5149 }
5150
5151 /* When an expr3 is present, try to evaluate it only once. In most
5152 cases expr3 is invariant for all elements of the allocation list.
5153 Only exceptions are arrays. Furthermore the standards prevent a
5154 dependency of expr3 on the objects in the allocate list. Therefore
5155 it is safe to pre-evaluate expr3 for complicated expressions, i.e.
5156 everything not a variable or constant. When an array allocation
5157 is wanted, then the following block nevertheless evaluates the
5158 _vptr, _len and element_size for expr3. */
5159 if (code->expr3)
5160 {
5161 bool vtab_needed = false;
5162 /* expr3_tmp gets the tree when code->expr3.mold is set, i.e.,
5163 the expression is only needed to get the _vptr, _len a.s.o. */
5164 tree expr3_tmp = NULL_TREE;
5165
5166 /* Figure whether we need the vtab from expr3. */
5167 for (al = code->ext.alloc.list; !vtab_needed && al != NULL;
5168 al = al->next)
5169 vtab_needed = (al->expr->ts.type == BT_CLASS);
5170
5171 /* A array expr3 needs the scalarizer, therefore do not process it
5172 here. */
5173 if (code->expr3->expr_type != EXPR_ARRAY
5174 && (code->expr3->rank == 0
5175 || code->expr3->expr_type == EXPR_FUNCTION)
5176 && (!code->expr3->symtree
5177 || !code->expr3->symtree->n.sym->as)
5178 && !gfc_is_class_array_ref (code->expr3, NULL))
5179 {
5180 /* When expr3 is a variable, i.e., a very simple expression,
5181 then convert it once here. */
5182 if ((code->expr3->expr_type == EXPR_VARIABLE)
5183 || code->expr3->expr_type == EXPR_CONSTANT)
5184 {
5185 if (!code->expr3->mold
5186 || code->expr3->ts.type == BT_CHARACTER
5187 || vtab_needed)
5188 {
5189 /* Convert expr3 to a tree. */
5190 gfc_init_se (&se, NULL);
5191 se.want_pointer = 1;
5192 gfc_conv_expr (&se, code->expr3);
5193 if (!code->expr3->mold)
5194 expr3 = se.expr;
5195 else
5196 expr3_tmp = se.expr;
5197 expr3_len = se.string_length;
5198 gfc_add_block_to_block (&block, &se.pre);
5199 gfc_add_block_to_block (&post, &se.post);
5200 }
5201 /* else expr3 = NULL_TREE set above. */
5202 }
5203 else
5204 {
5205 /* In all other cases evaluate the expr3 and create a
5206 temporary. */
5207 gfc_init_se (&se, NULL);
5208 if (code->expr3->rank != 0
5209 && code->expr3->expr_type == EXPR_FUNCTION
5210 && code->expr3->value.function.isym)
5211 gfc_conv_expr_descriptor (&se, code->expr3);
5212 else
5213 gfc_conv_expr_reference (&se, code->expr3);
5214 if (code->expr3->ts.type == BT_CLASS)
5215 gfc_conv_class_to_class (&se, code->expr3,
5216 code->expr3->ts,
5217 false, true,
5218 false, false);
5219 gfc_add_block_to_block (&block, &se.pre);
5220 gfc_add_block_to_block (&post, &se.post);
5221 /* Prevent aliasing, i.e., se.expr may be already a
5222 variable declaration. */
5223 if (!VAR_P (se.expr))
5224 {
5225 tmp = build_fold_indirect_ref_loc (input_location,
5226 se.expr);
5227 tmp = gfc_evaluate_now (tmp, &block);
5228 }
5229 else
5230 tmp = se.expr;
5231 if (!code->expr3->mold)
5232 expr3 = tmp;
5233 else
5234 expr3_tmp = tmp;
5235 /* When he length of a char array is easily available
5236 here, fix it for future use. */
5237 if (se.string_length)
5238 expr3_len = gfc_evaluate_now (se.string_length, &block);
5239 }
5240 }
5241
5242 /* Figure how to get the _vtab entry. This also obtains the tree
5243 expression for accessing the _len component, because only
5244 unlimited polymorphic objects, which are a subcategory of class
5245 types, have a _len component. */
5246 if (code->expr3->ts.type == BT_CLASS)
5247 {
5248 gfc_expr *rhs;
5249 /* Polymorphic SOURCE: VPTR must be determined at run time. */
5250 if (expr3 != NULL_TREE && (VAR_P (expr3) || !code->expr3->ref))
5251 tmp = gfc_class_vptr_get (expr3);
5252 else if (expr3_tmp != NULL_TREE
5253 && (VAR_P (expr3_tmp) ||!code->expr3->ref))
5254 tmp = gfc_class_vptr_get (expr3_tmp);
5255 else
5256 {
5257 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5258 gfc_add_vptr_component (rhs);
5259 gfc_init_se (&se, NULL);
5260 se.want_pointer = 1;
5261 gfc_conv_expr (&se, rhs);
5262 tmp = se.expr;
5263 gfc_free_expr (rhs);
5264 }
5265 /* Set the element size. */
5266 expr3_esize = gfc_vptr_size_get (tmp);
5267 if (vtab_needed)
5268 expr3_vptr = tmp;
5269 /* Initialize the ref to the _len component. */
5270 if (expr3_len == NULL_TREE && UNLIMITED_POLY (code->expr3))
5271 {
5272 /* Same like for retrieving the _vptr. */
5273 if (expr3 != NULL_TREE && !code->expr3->ref)
5274 expr3_len = gfc_class_len_get (expr3);
5275 else if (expr3_tmp != NULL_TREE && !code->expr3->ref)
5276 expr3_len = gfc_class_len_get (expr3_tmp);
5277 else
5278 {
5279 rhs = gfc_find_and_cut_at_last_class_ref (code->expr3);
5280 gfc_add_len_component (rhs);
5281 gfc_init_se (&se, NULL);
5282 gfc_conv_expr (&se, rhs);
5283 expr3_len = se.expr;
5284 gfc_free_expr (rhs);
5285 }
5286 }
5287 }
5288 else
5289 {
5290 /* When the object to allocate is polymorphic type, then it
5291 needs its vtab set correctly, so deduce the required _vtab
5292 and _len from the source expression. */
5293 if (vtab_needed)
5294 {
5295 /* VPTR is fixed at compile time. */
5296 gfc_symbol *vtab;
5297
5298 vtab = gfc_find_vtab (&code->expr3->ts);
5299 gcc_assert (vtab);
5300 expr3_vptr = gfc_get_symbol_decl (vtab);
5301 expr3_vptr = gfc_build_addr_expr (NULL_TREE,
5302 expr3_vptr);
5303 }
5304 /* _len component needs to be set, when ts is a character
5305 array. */
5306 if (expr3_len == NULL_TREE
5307 && code->expr3->ts.type == BT_CHARACTER)
5308 {
5309 if (code->expr3->ts.u.cl
5310 && code->expr3->ts.u.cl->length)
5311 {
5312 gfc_init_se (&se, NULL);
5313 gfc_conv_expr (&se, code->expr3->ts.u.cl->length);
5314 gfc_add_block_to_block (&block, &se.pre);
5315 expr3_len = gfc_evaluate_now (se.expr, &block);
5316 }
5317 gcc_assert (expr3_len);
5318 }
5319 /* For character arrays only the kind's size is needed, because
5320 the array mem_size is _len * (elem_size = kind_size).
5321 For all other get the element size in the normal way. */
5322 if (code->expr3->ts.type == BT_CHARACTER)
5323 expr3_esize = TYPE_SIZE_UNIT (
5324 gfc_get_char_type (code->expr3->ts.kind));
5325 else
5326 expr3_esize = TYPE_SIZE_UNIT (
5327 gfc_typenode_for_spec (&code->expr3->ts));
5328 }
5329 gcc_assert (expr3_esize);
5330 expr3_esize = fold_convert (sizetype, expr3_esize);
5331 }
5332 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5333 {
5334 /* Compute the explicit typespec given only once for all objects
5335 to allocate. */
5336 if (code->ext.alloc.ts.type != BT_CHARACTER)
5337 expr3_esize = TYPE_SIZE_UNIT (
5338 gfc_typenode_for_spec (&code->ext.alloc.ts));
5339 else
5340 {
5341 gfc_expr *sz;
5342 gcc_assert (code->ext.alloc.ts.u.cl->length != NULL);
5343 sz = gfc_copy_expr (code->ext.alloc.ts.u.cl->length);
5344 gfc_init_se (&se_sz, NULL);
5345 gfc_conv_expr (&se_sz, sz);
5346 gfc_free_expr (sz);
5347 tmp = gfc_get_char_type (code->ext.alloc.ts.kind);
5348 tmp = TYPE_SIZE_UNIT (tmp);
5349 tmp = fold_convert (TREE_TYPE (se_sz.expr), tmp);
5350 expr3_esize = fold_build2_loc (input_location, MULT_EXPR,
5351 TREE_TYPE (se_sz.expr),
5352 tmp, se_sz.expr);
5353 }
5354 }
5355
5356 /* Loop over all objects to allocate. */
5357 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5358 {
5359 expr = gfc_copy_expr (al->expr);
5360 /* UNLIMITED_POLY () needs the _data component to be set, when
5361 expr is a unlimited polymorphic object. But the _data component
5362 has not been set yet, so check the derived type's attr for the
5363 unlimited polymorphic flag to be safe. */
5364 upoly_expr = UNLIMITED_POLY (expr)
5365 || (expr->ts.type == BT_DERIVED
5366 && expr->ts.u.derived->attr.unlimited_polymorphic);
5367 gfc_init_se (&se, NULL);
5368
5369 /* For class types prepare the expressions to ref the _vptr
5370 and the _len component. The latter for unlimited polymorphic
5371 types only. */
5372 if (expr->ts.type == BT_CLASS)
5373 {
5374 gfc_expr *expr_ref_vptr, *expr_ref_len;
5375 gfc_add_data_component (expr);
5376 /* Prep the vptr handle. */
5377 expr_ref_vptr = gfc_copy_expr (al->expr);
5378 gfc_add_vptr_component (expr_ref_vptr);
5379 se.want_pointer = 1;
5380 gfc_conv_expr (&se, expr_ref_vptr);
5381 al_vptr = se.expr;
5382 se.want_pointer = 0;
5383 gfc_free_expr (expr_ref_vptr);
5384 /* Allocated unlimited polymorphic objects always have a _len
5385 component. */
5386 if (upoly_expr)
5387 {
5388 expr_ref_len = gfc_copy_expr (al->expr);
5389 gfc_add_len_component (expr_ref_len);
5390 gfc_conv_expr (&se, expr_ref_len);
5391 al_len = se.expr;
5392 gfc_free_expr (expr_ref_len);
5393 }
5394 else
5395 /* In a loop ensure that all loop variable dependent variables
5396 are initialized at the same spot in all execution paths. */
5397 al_len = NULL_TREE;
5398 }
5399 else
5400 al_vptr = al_len = NULL_TREE;
5401
5402 se.want_pointer = 1;
5403 se.descriptor_only = 1;
5404 gfc_conv_expr (&se, expr);
5405 if (expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5406 /* se.string_length now stores the .string_length variable of expr
5407 needed to allocate character(len=:) arrays. */
5408 al_len = se.string_length;
5409
5410 al_len_needs_set = al_len != NULL_TREE;
5411 /* When allocating an array one can not use much of the
5412 pre-evaluated expr3 expressions, because for most of them the
5413 scalarizer is needed which is not available in the pre-evaluation
5414 step. Therefore gfc_array_allocate () is responsible (and able)
5415 to handle the complete array allocation. Only the element size
5416 needs to be provided, which is done most of the time by the
5417 pre-evaluation step. */
5418 nelems = NULL_TREE;
5419 if (expr3_len && code->expr3->ts.type == BT_CHARACTER)
5420 /* When al is an array, then the element size for each element
5421 in the array is needed, which is the product of the len and
5422 esize for char arrays. */
5423 tmp = fold_build2_loc (input_location, MULT_EXPR,
5424 TREE_TYPE (expr3_esize), expr3_esize,
5425 fold_convert (TREE_TYPE (expr3_esize),
5426 expr3_len));
5427 else
5428 tmp = expr3_esize;
5429 if (!gfc_array_allocate (&se, expr, stat, errmsg, errlen,
5430 label_finish, tmp, &nelems, code->expr3))
5431 {
5432 /* A scalar or derived type. First compute the size to
5433 allocate.
5434
5435 expr3_len is set when expr3 is an unlimited polymorphic
5436 object or a deferred length string. */
5437 if (expr3_len != NULL_TREE)
5438 {
5439 tmp = fold_convert (TREE_TYPE (expr3_esize), expr3_len);
5440 tmp = fold_build2_loc (input_location, MULT_EXPR,
5441 TREE_TYPE (expr3_esize),
5442 expr3_esize, tmp);
5443 if (code->expr3->ts.type != BT_CLASS)
5444 /* expr3 is a deferred length string, i.e., we are
5445 done. */
5446 memsz = tmp;
5447 else
5448 {
5449 /* For unlimited polymorphic enties build
5450 (len > 0) ? element_size * len : element_size
5451 to compute the number of bytes to allocate.
5452 This allows the allocation of unlimited polymorphic
5453 objects from an expr3 that is also unlimited
5454 polymorphic and stores a _len dependent object,
5455 e.g., a string. */
5456 memsz = fold_build2_loc (input_location, GT_EXPR,
5457 boolean_type_node, expr3_len,
5458 integer_zero_node);
5459 memsz = fold_build3_loc (input_location, COND_EXPR,
5460 TREE_TYPE (expr3_esize),
5461 memsz, tmp, expr3_esize);
5462 }
5463 }
5464 else if (expr3_esize != NULL_TREE)
5465 /* Any other object in expr3 just needs element size in
5466 bytes. */
5467 memsz = expr3_esize;
5468 else if ((expr->ts.type == BT_CHARACTER && expr->ts.deferred)
5469 || (upoly_expr
5470 && code->ext.alloc.ts.type == BT_CHARACTER))
5471 {
5472 /* Allocating deferred length char arrays need the length
5473 to allocate in the alloc_type_spec. But also unlimited
5474 polymorphic objects may be allocated as char arrays.
5475 Both are handled here. */
5476 gfc_init_se (&se_sz, NULL);
5477 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5478 gfc_add_block_to_block (&se.pre, &se_sz.pre);
5479 se_sz.expr = gfc_evaluate_now (se_sz.expr, &se.pre);
5480 gfc_add_block_to_block (&se.pre, &se_sz.post);
5481 expr3_len = se_sz.expr;
5482 tmp_expr3_len_flag = true;
5483 tmp = TYPE_SIZE_UNIT (
5484 gfc_get_char_type (code->ext.alloc.ts.kind));
5485 memsz = fold_build2_loc (input_location, MULT_EXPR,
5486 TREE_TYPE (tmp),
5487 fold_convert (TREE_TYPE (tmp),
5488 expr3_len),
5489 tmp);
5490 }
5491 else if (expr->ts.type == BT_CHARACTER)
5492 {
5493 /* Compute the number of bytes needed to allocate a fixed
5494 length char array. */
5495 gcc_assert (se.string_length != NULL_TREE);
5496 tmp = TYPE_SIZE_UNIT (gfc_get_char_type (expr->ts.kind));
5497 memsz = fold_build2_loc (input_location, MULT_EXPR,
5498 TREE_TYPE (tmp), tmp,
5499 fold_convert (TREE_TYPE (tmp),
5500 se.string_length));
5501 }
5502 else if (code->ext.alloc.ts.type != BT_UNKNOWN)
5503 /* Handle all types, where the alloc_type_spec is set. */
5504 memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
5505 else
5506 /* Handle size computation of the type declared to alloc. */
5507 memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
5508
5509 /* Allocate - for non-pointers with re-alloc checking. */
5510 if (gfc_expr_attr (expr).allocatable)
5511 gfc_allocate_allocatable (&se.pre, se.expr, memsz, NULL_TREE,
5512 stat, errmsg, errlen, label_finish,
5513 expr);
5514 else
5515 gfc_allocate_using_malloc (&se.pre, se.expr, memsz, stat);
5516
5517 if (al->expr->ts.type == BT_DERIVED
5518 && expr->ts.u.derived->attr.alloc_comp)
5519 {
5520 tmp = build_fold_indirect_ref_loc (input_location, se.expr);
5521 tmp = gfc_nullify_alloc_comp (expr->ts.u.derived, tmp, 0);
5522 gfc_add_expr_to_block (&se.pre, tmp);
5523 }
5524 }
5525 else
5526 {
5527 if (expr->ts.type == BT_CHARACTER && al_len != NULL_TREE
5528 && expr3_len != NULL_TREE)
5529 {
5530 /* Arrays need to have a _len set before the array
5531 descriptor is filled. */
5532 gfc_add_modify (&block, al_len,
5533 fold_convert (TREE_TYPE (al_len), expr3_len));
5534 /* Prevent setting the length twice. */
5535 al_len_needs_set = false;
5536 }
5537 }
5538
5539 gfc_add_block_to_block (&block, &se.pre);
5540
5541 /* Error checking -- Note: ERRMSG only makes sense with STAT. */
5542 if (code->expr1)
5543 {
5544 tmp = build1_v (GOTO_EXPR, label_errmsg);
5545 parm = fold_build2_loc (input_location, NE_EXPR,
5546 boolean_type_node, stat,
5547 build_int_cst (TREE_TYPE (stat), 0));
5548 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
5549 gfc_unlikely (parm, PRED_FORTRAN_FAIL_ALLOC),
5550 tmp, build_empty_stmt (input_location));
5551 gfc_add_expr_to_block (&block, tmp);
5552 }
5553
5554 /* Set the vptr. */
5555 if (al_vptr != NULL_TREE)
5556 {
5557 if (expr3_vptr != NULL_TREE)
5558 /* The vtab is already known, so just assign it. */
5559 gfc_add_modify (&block, al_vptr,
5560 fold_convert (TREE_TYPE (al_vptr), expr3_vptr));
5561 else
5562 {
5563 /* VPTR is fixed at compile time. */
5564 gfc_symbol *vtab;
5565 gfc_typespec *ts;
5566
5567 if (code->expr3)
5568 /* Although expr3 is pre-evaluated above, it may happen,
5569 that for arrays or in mold= cases the pre-evaluation
5570 was not successful. In these rare cases take the vtab
5571 from the typespec of expr3 here. */
5572 ts = &code->expr3->ts;
5573 else if (code->ext.alloc.ts.type == BT_DERIVED || upoly_expr)
5574 /* The alloc_type_spec gives the type to allocate or the
5575 al is unlimited polymorphic, which enforces the use of
5576 an alloc_type_spec that is not necessarily a BT_DERIVED. */
5577 ts = &code->ext.alloc.ts;
5578 else
5579 /* Prepare for setting the vtab as declared. */
5580 ts = &expr->ts;
5581
5582 vtab = gfc_find_vtab (ts);
5583 gcc_assert (vtab);
5584 tmp = gfc_build_addr_expr (NULL_TREE,
5585 gfc_get_symbol_decl (vtab));
5586 gfc_add_modify (&block, al_vptr,
5587 fold_convert (TREE_TYPE (al_vptr), tmp));
5588 }
5589 }
5590
5591 /* Add assignment for string length. */
5592 if (al_len != NULL_TREE && al_len_needs_set)
5593 {
5594 if (expr3_len != NULL_TREE)
5595 {
5596 gfc_add_modify (&block, al_len,
5597 fold_convert (TREE_TYPE (al_len),
5598 expr3_len));
5599 /* When tmp_expr3_len_flag is set, then expr3_len is
5600 abused to carry the length information from the
5601 alloc_type. Clear it to prevent setting incorrect len
5602 information in future loop iterations. */
5603 if (tmp_expr3_len_flag)
5604 /* No need to reset tmp_expr3_len_flag, because the
5605 presence of an expr3 can not change within in the
5606 loop. */
5607 expr3_len = NULL_TREE;
5608 }
5609 else if (code->ext.alloc.ts.type == BT_CHARACTER
5610 && code->ext.alloc.ts.u.cl->length)
5611 {
5612 /* Cover the cases where a string length is explicitly
5613 specified by a type spec for deferred length character
5614 arrays or unlimited polymorphic objects without a
5615 source= or mold= expression. */
5616 gfc_init_se (&se_sz, NULL);
5617 gfc_conv_expr (&se_sz, code->ext.alloc.ts.u.cl->length);
5618 gfc_add_modify (&block, al_len,
5619 fold_convert (TREE_TYPE (al_len),
5620 se_sz.expr));
5621 }
5622 else
5623 /* No length information needed, because type to allocate
5624 has no length. Set _len to 0. */
5625 gfc_add_modify (&block, al_len,
5626 fold_convert (TREE_TYPE (al_len),
5627 integer_zero_node));
5628 }
5629 if (code->expr3 && !code->expr3->mold)
5630 {
5631 /* Initialization via SOURCE block
5632 (or static default initializer). */
5633 gfc_expr *rhs = gfc_copy_expr (code->expr3);
5634 if (expr3 != NULL_TREE
5635 && ((POINTER_TYPE_P (TREE_TYPE (expr3))
5636 && TREE_CODE (expr3) != POINTER_PLUS_EXPR)
5637 || VAR_P (expr3))
5638 && code->expr3->ts.type == BT_CLASS
5639 && (expr->ts.type == BT_CLASS
5640 || expr->ts.type == BT_DERIVED))
5641 {
5642 tree to;
5643 to = VAR_P (se.expr) ? se.expr : TREE_OPERAND (se.expr, 0);
5644 tmp = gfc_copy_class_to_class (expr3, to,
5645 nelems, upoly_expr);
5646 }
5647 else if (code->expr3->ts.type == BT_CHARACTER)
5648 {
5649 tmp = INDIRECT_REF_P (se.expr) ?
5650 se.expr :
5651 build_fold_indirect_ref_loc (input_location,
5652 se.expr);
5653 gfc_trans_string_copy (&block, al_len, tmp,
5654 code->expr3->ts.kind,
5655 expr3_len, expr3,
5656 code->expr3->ts.kind);
5657 tmp = NULL_TREE;
5658 }
5659 else if (al->expr->ts.type == BT_CLASS)
5660 {
5661 gfc_actual_arglist *actual, *last_arg;
5662 gfc_expr *ppc;
5663 gfc_code *ppc_code;
5664 gfc_ref *ref, *dataref;
5665
5666 /* Do a polymorphic deep copy. */
5667 actual = gfc_get_actual_arglist ();
5668 actual->expr = gfc_copy_expr (rhs);
5669 if (rhs->ts.type == BT_CLASS)
5670 gfc_add_data_component (actual->expr);
5671 last_arg = actual->next = gfc_get_actual_arglist ();
5672 last_arg->expr = gfc_copy_expr (al->expr);
5673 last_arg->expr->ts.type = BT_CLASS;
5674 gfc_add_data_component (last_arg->expr);
5675
5676 dataref = NULL;
5677 /* Make sure we go up through the reference chain to
5678 the _data reference, where the arrayspec is found. */
5679 for (ref = last_arg->expr->ref; ref; ref = ref->next)
5680 if (ref->type == REF_COMPONENT
5681 && strcmp (ref->u.c.component->name, "_data") == 0)
5682 dataref = ref;
5683
5684 if (dataref && dataref->u.c.component->as)
5685 {
5686 int dim;
5687 gfc_expr *temp;
5688 gfc_ref *ref = dataref->next;
5689 ref->u.ar.type = AR_SECTION;
5690 /* We have to set up the array reference to give ranges
5691 in all dimensions and ensure that the end and stride
5692 are set so that the copy can be scalarized. */
5693 dim = 0;
5694 for (; dim < dataref->u.c.component->as->rank; dim++)
5695 {
5696 ref->u.ar.dimen_type[dim] = DIMEN_RANGE;
5697 if (ref->u.ar.end[dim] == NULL)
5698 {
5699 ref->u.ar.end[dim] = ref->u.ar.start[dim];
5700 temp = gfc_get_int_expr (gfc_default_integer_kind,
5701 &al->expr->where, 1);
5702 ref->u.ar.start[dim] = temp;
5703 }
5704 temp = gfc_subtract (gfc_copy_expr (ref->u.ar.end[dim]),
5705 gfc_copy_expr (ref->u.ar.start[dim]));
5706 temp = gfc_add (gfc_get_int_expr (gfc_default_integer_kind,
5707 &al->expr->where, 1),
5708 temp);
5709 }
5710 }
5711 if (rhs->ts.type == BT_CLASS)
5712 {
5713 if (rhs->ref)
5714 ppc = gfc_find_and_cut_at_last_class_ref (rhs);
5715 else
5716 ppc = gfc_copy_expr (rhs);
5717 gfc_add_vptr_component (ppc);
5718 }
5719 else
5720 ppc = gfc_lval_expr_from_sym (gfc_find_vtab (&rhs->ts));
5721 gfc_add_component_ref (ppc, "_copy");
5722
5723 ppc_code = gfc_get_code (EXEC_CALL);
5724 ppc_code->resolved_sym = ppc->symtree->n.sym;
5725 ppc_code->loc = al->expr->where;
5726 /* Although '_copy' is set to be elemental in class.c, it is
5727 not staying that way. Find out why, sometime.... */
5728 ppc_code->resolved_sym->attr.elemental = 1;
5729 ppc_code->ext.actual = actual;
5730 ppc_code->expr1 = ppc;
5731 /* Since '_copy' is elemental, the scalarizer will take care
5732 of arrays in gfc_trans_call. */
5733 tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
5734 /* We need to add the
5735 if (al_len > 0)
5736 al_vptr->copy (expr3_data, al_data, expr3_len, al_len);
5737 else
5738 al_vptr->copy (expr3_data, al_data);
5739 block, because al is unlimited polymorphic or a deferred
5740 length char array, whose copy routine needs the array lengths
5741 as third and fourth arguments. */
5742 if (al_len && UNLIMITED_POLY (code->expr3))
5743 {
5744 tree stdcopy, extcopy;
5745 /* Add al%_len. */
5746 last_arg->next = gfc_get_actual_arglist ();
5747 last_arg = last_arg->next;
5748 last_arg->expr = gfc_find_and_cut_at_last_class_ref (
5749 al->expr);
5750 gfc_add_len_component (last_arg->expr);
5751 /* Add expr3's length. */
5752 last_arg->next = gfc_get_actual_arglist ();
5753 last_arg = last_arg->next;
5754 if (code->expr3->ts.type == BT_CLASS)
5755 {
5756 last_arg->expr =
5757 gfc_find_and_cut_at_last_class_ref (code->expr3);
5758 gfc_add_len_component (last_arg->expr);
5759 }
5760 else if (code->expr3->ts.type == BT_CHARACTER)
5761 last_arg->expr =
5762 gfc_copy_expr (code->expr3->ts.u.cl->length);
5763 else
5764 gcc_unreachable ();
5765
5766 stdcopy = tmp;
5767 extcopy = gfc_trans_call (ppc_code, true, NULL, NULL, false);
5768
5769 tmp = fold_build2_loc (input_location, GT_EXPR,
5770 boolean_type_node, expr3_len,
5771 integer_zero_node);
5772 tmp = fold_build3_loc (input_location, COND_EXPR,
5773 void_type_node, tmp, extcopy, stdcopy);
5774 }
5775 gfc_free_statements (ppc_code);
5776 }
5777 else
5778 {
5779 /* Switch off automatic reallocation since we have just
5780 done the ALLOCATE. */
5781 int realloc_lhs = flag_realloc_lhs;
5782 flag_realloc_lhs = 0;
5783 tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
5784 rhs, false, false);
5785 flag_realloc_lhs = realloc_lhs;
5786 }
5787 gfc_free_expr (rhs);
5788 gfc_add_expr_to_block (&block, tmp);
5789 }
5790 else if (code->expr3 && code->expr3->mold
5791 && code->expr3->ts.type == BT_CLASS)
5792 {
5793 /* Since the _vptr has already been assigned to the allocate
5794 object, we can use gfc_copy_class_to_class in its
5795 initialization mode. */
5796 tmp = TREE_OPERAND (se.expr, 0);
5797 tmp = gfc_copy_class_to_class (NULL_TREE, tmp, nelems,
5798 upoly_expr);
5799 gfc_add_expr_to_block (&block, tmp);
5800 }
5801
5802 gfc_free_expr (expr);
5803 } // for-loop
5804
5805 /* STAT. */
5806 if (code->expr1)
5807 {
5808 tmp = build1_v (LABEL_EXPR, label_errmsg);
5809 gfc_add_expr_to_block (&block, tmp);
5810 }
5811
5812 /* ERRMSG - only useful if STAT is present. */
5813 if (code->expr1 && code->expr2)
5814 {
5815 const char *msg = "Attempt to allocate an allocated object";
5816 tree slen, dlen, errmsg_str;
5817 stmtblock_t errmsg_block;
5818
5819 gfc_init_block (&errmsg_block);
5820
5821 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
5822 gfc_add_modify (&errmsg_block, errmsg_str,
5823 gfc_build_addr_expr (pchar_type_node,
5824 gfc_build_localized_cstring_const (msg)));
5825
5826 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
5827 dlen = gfc_get_expr_charlen (code->expr2);
5828 slen = fold_build2_loc (input_location, MIN_EXPR,
5829 TREE_TYPE (slen), dlen, slen);
5830
5831 gfc_trans_string_copy (&errmsg_block, dlen, errmsg,
5832 code->expr2->ts.kind,
5833 slen, errmsg_str,
5834 gfc_default_character_kind);
5835 dlen = gfc_finish_block (&errmsg_block);
5836
5837 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5838 stat, build_int_cst (TREE_TYPE (stat), 0));
5839
5840 tmp = build3_v (COND_EXPR, tmp,
5841 dlen, build_empty_stmt (input_location));
5842
5843 gfc_add_expr_to_block (&block, tmp);
5844 }
5845
5846 /* STAT block. */
5847 if (code->expr1)
5848 {
5849 if (TREE_USED (label_finish))
5850 {
5851 tmp = build1_v (LABEL_EXPR, label_finish);
5852 gfc_add_expr_to_block (&block, tmp);
5853 }
5854
5855 gfc_init_se (&se, NULL);
5856 gfc_conv_expr_lhs (&se, code->expr1);
5857 tmp = convert (TREE_TYPE (se.expr), stat);
5858 gfc_add_modify (&block, se.expr, tmp);
5859 }
5860
5861 gfc_add_block_to_block (&block, &se.post);
5862 gfc_add_block_to_block (&block, &post);
5863
5864 return gfc_finish_block (&block);
5865 }
5866
5867
5868 /* Translate a DEALLOCATE statement. */
5869
5870 tree
5871 gfc_trans_deallocate (gfc_code *code)
5872 {
5873 gfc_se se;
5874 gfc_alloc *al;
5875 tree apstat, pstat, stat, errmsg, errlen, tmp;
5876 tree label_finish, label_errmsg;
5877 stmtblock_t block;
5878
5879 pstat = apstat = stat = errmsg = errlen = tmp = NULL_TREE;
5880 label_finish = label_errmsg = NULL_TREE;
5881
5882 gfc_start_block (&block);
5883
5884 /* Count the number of failed deallocations. If deallocate() was
5885 called with STAT= , then set STAT to the count. If deallocate
5886 was called with ERRMSG, then set ERRMG to a string. */
5887 if (code->expr1)
5888 {
5889 tree gfc_int4_type_node = gfc_get_int_type (4);
5890
5891 stat = gfc_create_var (gfc_int4_type_node, "stat");
5892 pstat = gfc_build_addr_expr (NULL_TREE, stat);
5893
5894 /* GOTO destinations. */
5895 label_errmsg = gfc_build_label_decl (NULL_TREE);
5896 label_finish = gfc_build_label_decl (NULL_TREE);
5897 TREE_USED (label_finish) = 0;
5898 }
5899
5900 /* Set ERRMSG - only needed if STAT is available. */
5901 if (code->expr1 && code->expr2)
5902 {
5903 gfc_init_se (&se, NULL);
5904 se.want_pointer = 1;
5905 gfc_conv_expr_lhs (&se, code->expr2);
5906 errmsg = se.expr;
5907 errlen = se.string_length;
5908 }
5909
5910 for (al = code->ext.alloc.list; al != NULL; al = al->next)
5911 {
5912 gfc_expr *expr = gfc_copy_expr (al->expr);
5913 gcc_assert (expr->expr_type == EXPR_VARIABLE);
5914
5915 if (expr->ts.type == BT_CLASS)
5916 gfc_add_data_component (expr);
5917
5918 gfc_init_se (&se, NULL);
5919 gfc_start_block (&se.pre);
5920
5921 se.want_pointer = 1;
5922 se.descriptor_only = 1;
5923 gfc_conv_expr (&se, expr);
5924
5925 if (expr->rank || gfc_is_coarray (expr))
5926 {
5927 gfc_ref *ref;
5928
5929 if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp
5930 && !gfc_is_finalizable (expr->ts.u.derived, NULL))
5931 {
5932 gfc_ref *last = NULL;
5933
5934 for (ref = expr->ref; ref; ref = ref->next)
5935 if (ref->type == REF_COMPONENT)
5936 last = ref;
5937
5938 /* Do not deallocate the components of a derived type
5939 ultimate pointer component. */
5940 if (!(last && last->u.c.component->attr.pointer)
5941 && !(!last && expr->symtree->n.sym->attr.pointer))
5942 {
5943 tmp = gfc_deallocate_alloc_comp (expr->ts.u.derived, se.expr,
5944 expr->rank);
5945 gfc_add_expr_to_block (&se.pre, tmp);
5946 }
5947 }
5948
5949 if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se.expr)))
5950 {
5951 tmp = gfc_array_deallocate (se.expr, pstat, errmsg, errlen,
5952 label_finish, expr);
5953 gfc_add_expr_to_block (&se.pre, tmp);
5954 }
5955 else if (TREE_CODE (se.expr) == COMPONENT_REF
5956 && TREE_CODE (TREE_TYPE (se.expr)) == ARRAY_TYPE
5957 && TREE_CODE (TREE_TYPE (TREE_TYPE (se.expr)))
5958 == RECORD_TYPE)
5959 {
5960 /* class.c(finalize_component) generates these, when a
5961 finalizable entity has a non-allocatable derived type array
5962 component, which has allocatable components. Obtain the
5963 derived type of the array and deallocate the allocatable
5964 components. */
5965 for (ref = expr->ref; ref; ref = ref->next)
5966 {
5967 if (ref->u.c.component->attr.dimension
5968 && ref->u.c.component->ts.type == BT_DERIVED)
5969 break;
5970 }
5971
5972 if (ref && ref->u.c.component->ts.u.derived->attr.alloc_comp
5973 && !gfc_is_finalizable (ref->u.c.component->ts.u.derived,
5974 NULL))
5975 {
5976 tmp = gfc_deallocate_alloc_comp
5977 (ref->u.c.component->ts.u.derived,
5978 se.expr, expr->rank);
5979 gfc_add_expr_to_block (&se.pre, tmp);
5980 }
5981 }
5982
5983 if (al->expr->ts.type == BT_CLASS)
5984 {
5985 gfc_reset_vptr (&se.pre, al->expr);
5986 if (UNLIMITED_POLY (al->expr)
5987 || (al->expr->ts.type == BT_DERIVED
5988 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
5989 /* Clear _len, too. */
5990 gfc_reset_len (&se.pre, al->expr);
5991 }
5992 }
5993 else
5994 {
5995 tmp = gfc_deallocate_scalar_with_status (se.expr, pstat, false,
5996 al->expr, al->expr->ts);
5997 gfc_add_expr_to_block (&se.pre, tmp);
5998
5999 /* Set to zero after deallocation. */
6000 tmp = fold_build2_loc (input_location, MODIFY_EXPR, void_type_node,
6001 se.expr,
6002 build_int_cst (TREE_TYPE (se.expr), 0));
6003 gfc_add_expr_to_block (&se.pre, tmp);
6004
6005 if (al->expr->ts.type == BT_CLASS)
6006 {
6007 gfc_reset_vptr (&se.pre, al->expr);
6008 if (UNLIMITED_POLY (al->expr)
6009 || (al->expr->ts.type == BT_DERIVED
6010 && al->expr->ts.u.derived->attr.unlimited_polymorphic))
6011 /* Clear _len, too. */
6012 gfc_reset_len (&se.pre, al->expr);
6013 }
6014 }
6015
6016 if (code->expr1)
6017 {
6018 tree cond;
6019
6020 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6021 build_int_cst (TREE_TYPE (stat), 0));
6022 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6023 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC),
6024 build1_v (GOTO_EXPR, label_errmsg),
6025 build_empty_stmt (input_location));
6026 gfc_add_expr_to_block (&se.pre, tmp);
6027 }
6028
6029 tmp = gfc_finish_block (&se.pre);
6030 gfc_add_expr_to_block (&block, tmp);
6031 gfc_free_expr (expr);
6032 }
6033
6034 if (code->expr1)
6035 {
6036 tmp = build1_v (LABEL_EXPR, label_errmsg);
6037 gfc_add_expr_to_block (&block, tmp);
6038 }
6039
6040 /* Set ERRMSG - only needed if STAT is available. */
6041 if (code->expr1 && code->expr2)
6042 {
6043 const char *msg = "Attempt to deallocate an unallocated object";
6044 stmtblock_t errmsg_block;
6045 tree errmsg_str, slen, dlen, cond;
6046
6047 gfc_init_block (&errmsg_block);
6048
6049 errmsg_str = gfc_create_var (pchar_type_node, "ERRMSG");
6050 gfc_add_modify (&errmsg_block, errmsg_str,
6051 gfc_build_addr_expr (pchar_type_node,
6052 gfc_build_localized_cstring_const (msg)));
6053 slen = build_int_cst (gfc_charlen_type_node, ((int) strlen (msg)));
6054 dlen = gfc_get_expr_charlen (code->expr2);
6055
6056 gfc_trans_string_copy (&errmsg_block, dlen, errmsg, code->expr2->ts.kind,
6057 slen, errmsg_str, gfc_default_character_kind);
6058 tmp = gfc_finish_block (&errmsg_block);
6059
6060 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, stat,
6061 build_int_cst (TREE_TYPE (stat), 0));
6062 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
6063 gfc_unlikely (cond, PRED_FORTRAN_FAIL_ALLOC), tmp,
6064 build_empty_stmt (input_location));
6065
6066 gfc_add_expr_to_block (&block, tmp);
6067 }
6068
6069 if (code->expr1 && TREE_USED (label_finish))
6070 {
6071 tmp = build1_v (LABEL_EXPR, label_finish);
6072 gfc_add_expr_to_block (&block, tmp);
6073 }
6074
6075 /* Set STAT. */
6076 if (code->expr1)
6077 {
6078 gfc_init_se (&se, NULL);
6079 gfc_conv_expr_lhs (&se, code->expr1);
6080 tmp = convert (TREE_TYPE (se.expr), stat);
6081 gfc_add_modify (&block, se.expr, tmp);
6082 }
6083
6084 return gfc_finish_block (&block);
6085 }
6086
6087 #include "gt-fortran-trans-stmt.h"