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