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