* data.c, dependency.c, f95-lang.c, io.c, trans-array.c,
[official-gcc.git] / gcc / fortran / trans-stmt.c
blob2d2fe8bf8b7f26c3dce8e6f217fbeef12c8816c1
1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tree.h"
28 #include "tree-gimple.h"
29 #include "ggc.h"
30 #include "toplev.h"
31 #include "real.h"
32 #include "gfortran.h"
33 #include "trans.h"
34 #include "trans-stmt.h"
35 #include "trans-types.h"
36 #include "trans-array.h"
37 #include "trans-const.h"
38 #include "arith.h"
40 int has_alternate_specifier;
42 typedef struct iter_info
44 tree var;
45 tree start;
46 tree end;
47 tree step;
48 struct iter_info *next;
50 iter_info;
52 typedef struct temporary_list
54 tree temporary;
55 struct temporary_list *next;
57 temporary_list;
59 typedef struct forall_info
61 iter_info *this_loop;
62 tree mask;
63 tree pmask;
64 tree maskindex;
65 int nvar;
66 tree size;
67 struct forall_info *outer;
68 struct forall_info *next_nest;
70 forall_info;
72 static void gfc_trans_where_2 (gfc_code *, tree, tree, forall_info *,
73 stmtblock_t *, temporary_list **temp);
75 /* Translate a F95 label number to a LABEL_EXPR. */
77 tree
78 gfc_trans_label_here (gfc_code * code)
80 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
83 /* Translate a label assignment statement. */
84 tree
85 gfc_trans_label_assign (gfc_code * code)
87 tree label_tree;
88 gfc_se se;
89 tree len;
90 tree addr;
91 tree len_tree;
92 char *label_str;
93 int label_len;
95 /* Start a new block. */
96 gfc_init_se (&se, NULL);
97 gfc_start_block (&se.pre);
98 gfc_conv_expr (&se, code->expr);
99 len = GFC_DECL_STRING_LEN (se.expr);
100 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
102 label_tree = gfc_get_label_decl (code->label);
104 if (code->label->defined == ST_LABEL_TARGET)
106 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
107 len_tree = integer_minus_one_node;
109 else
111 label_str = code->label->format->value.character.string;
112 label_len = code->label->format->value.character.length;
113 len_tree = build_int_cst (NULL_TREE, label_len);
114 label_tree = gfc_build_string_const (label_len + 1, label_str);
115 label_tree = gfc_build_addr_expr (pchar_type_node, label_tree);
118 gfc_add_modify_expr (&se.pre, len, len_tree);
119 gfc_add_modify_expr (&se.pre, addr, label_tree);
121 return gfc_finish_block (&se.pre);
124 /* Translate a GOTO statement. */
126 tree
127 gfc_trans_goto (gfc_code * code)
129 tree assigned_goto;
130 tree target;
131 tree tmp;
132 tree assign_error;
133 tree range_error;
134 gfc_se se;
137 if (code->label != NULL)
138 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
140 /* ASSIGNED GOTO. */
141 gfc_init_se (&se, NULL);
142 gfc_start_block (&se.pre);
143 gfc_conv_expr (&se, code->expr);
144 assign_error =
145 gfc_build_cstring_const ("Assigned label is not a target label");
146 tmp = GFC_DECL_STRING_LEN (se.expr);
147 tmp = build2 (NE_EXPR, boolean_type_node, tmp, integer_minus_one_node);
148 gfc_trans_runtime_check (tmp, assign_error, &se.pre);
150 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
151 target = build1 (GOTO_EXPR, void_type_node, assigned_goto);
153 code = code->block;
154 if (code == NULL)
156 gfc_add_expr_to_block (&se.pre, target);
157 return gfc_finish_block (&se.pre);
160 /* Check the label list. */
161 range_error = gfc_build_cstring_const ("Assigned label is not in the list");
165 tmp = gfc_get_label_decl (code->label);
166 tmp = gfc_build_addr_expr (pvoid_type_node, tmp);
167 tmp = build2 (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
168 tmp = build3_v (COND_EXPR, tmp, target, build_empty_stmt ());
169 gfc_add_expr_to_block (&se.pre, tmp);
170 code = code->block;
172 while (code != NULL);
173 gfc_trans_runtime_check (boolean_true_node, range_error, &se.pre);
174 return gfc_finish_block (&se.pre);
178 /* Translate an ENTRY statement. Just adds a label for this entry point. */
179 tree
180 gfc_trans_entry (gfc_code * code)
182 return build1_v (LABEL_EXPR, code->ext.entry->label);
186 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
188 tree
189 gfc_trans_call (gfc_code * code)
191 gfc_se se;
193 /* A CALL starts a new block because the actual arguments may have to
194 be evaluated first. */
195 gfc_init_se (&se, NULL);
196 gfc_start_block (&se.pre);
198 gcc_assert (code->resolved_sym);
199 has_alternate_specifier = 0;
201 /* Translate the call. */
202 gfc_conv_function_call (&se, code->resolved_sym, code->ext.actual);
204 /* A subroutine without side-effect, by definition, does nothing! */
205 TREE_SIDE_EFFECTS (se.expr) = 1;
207 /* Chain the pieces together and return the block. */
208 if (has_alternate_specifier)
210 gfc_code *select_code;
211 gfc_symbol *sym;
212 select_code = code->next;
213 gcc_assert(select_code->op == EXEC_SELECT);
214 sym = select_code->expr->symtree->n.sym;
215 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
216 gfc_add_modify_expr (&se.pre, sym->backend_decl, se.expr);
218 else
219 gfc_add_expr_to_block (&se.pre, se.expr);
221 gfc_add_block_to_block (&se.pre, &se.post);
222 return gfc_finish_block (&se.pre);
226 /* Translate the RETURN statement. */
228 tree
229 gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
231 if (code->expr)
233 gfc_se se;
234 tree tmp;
235 tree result;
237 /* if code->expr is not NULL, this return statement must appear
238 in a subroutine and current_fake_result_decl has already
239 been generated. */
241 result = gfc_get_fake_result_decl (NULL);
242 if (!result)
244 gfc_warning ("An alternate return at %L without a * dummy argument",
245 &code->expr->where);
246 return build1_v (GOTO_EXPR, gfc_get_return_label ());
249 /* Start a new block for this statement. */
250 gfc_init_se (&se, NULL);
251 gfc_start_block (&se.pre);
253 gfc_conv_expr (&se, code->expr);
255 tmp = build2 (MODIFY_EXPR, TREE_TYPE (result), result, se.expr);
256 gfc_add_expr_to_block (&se.pre, tmp);
258 tmp = build1_v (GOTO_EXPR, gfc_get_return_label ());
259 gfc_add_expr_to_block (&se.pre, tmp);
260 gfc_add_block_to_block (&se.pre, &se.post);
261 return gfc_finish_block (&se.pre);
263 else
264 return build1_v (GOTO_EXPR, gfc_get_return_label ());
268 /* Translate the PAUSE statement. We have to translate this statement
269 to a runtime library call. */
271 tree
272 gfc_trans_pause (gfc_code * code)
274 tree gfc_int4_type_node = gfc_get_int_type (4);
275 gfc_se se;
276 tree args;
277 tree tmp;
278 tree fndecl;
280 /* Start a new block for this statement. */
281 gfc_init_se (&se, NULL);
282 gfc_start_block (&se.pre);
285 if (code->expr == NULL)
287 tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
288 args = gfc_chainon_list (NULL_TREE, tmp);
289 fndecl = gfor_fndecl_pause_numeric;
291 else
293 gfc_conv_expr_reference (&se, code->expr);
294 args = gfc_chainon_list (NULL_TREE, se.expr);
295 args = gfc_chainon_list (args, se.string_length);
296 fndecl = gfor_fndecl_pause_string;
299 tmp = gfc_build_function_call (fndecl, args);
300 gfc_add_expr_to_block (&se.pre, tmp);
302 gfc_add_block_to_block (&se.pre, &se.post);
304 return gfc_finish_block (&se.pre);
308 /* Translate the STOP statement. We have to translate this statement
309 to a runtime library call. */
311 tree
312 gfc_trans_stop (gfc_code * code)
314 tree gfc_int4_type_node = gfc_get_int_type (4);
315 gfc_se se;
316 tree args;
317 tree tmp;
318 tree fndecl;
320 /* Start a new block for this statement. */
321 gfc_init_se (&se, NULL);
322 gfc_start_block (&se.pre);
325 if (code->expr == NULL)
327 tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
328 args = gfc_chainon_list (NULL_TREE, tmp);
329 fndecl = gfor_fndecl_stop_numeric;
331 else
333 gfc_conv_expr_reference (&se, code->expr);
334 args = gfc_chainon_list (NULL_TREE, se.expr);
335 args = gfc_chainon_list (args, se.string_length);
336 fndecl = gfor_fndecl_stop_string;
339 tmp = gfc_build_function_call (fndecl, args);
340 gfc_add_expr_to_block (&se.pre, tmp);
342 gfc_add_block_to_block (&se.pre, &se.post);
344 return gfc_finish_block (&se.pre);
348 /* Generate GENERIC for the IF construct. This function also deals with
349 the simple IF statement, because the front end translates the IF
350 statement into an IF construct.
352 We translate:
354 IF (cond) THEN
355 then_clause
356 ELSEIF (cond2)
357 elseif_clause
358 ELSE
359 else_clause
360 ENDIF
362 into:
364 pre_cond_s;
365 if (cond_s)
367 then_clause;
369 else
371 pre_cond_s
372 if (cond_s)
374 elseif_clause
376 else
378 else_clause;
382 where COND_S is the simplified version of the predicate. PRE_COND_S
383 are the pre side-effects produced by the translation of the
384 conditional.
385 We need to build the chain recursively otherwise we run into
386 problems with folding incomplete statements. */
388 static tree
389 gfc_trans_if_1 (gfc_code * code)
391 gfc_se if_se;
392 tree stmt, elsestmt;
394 /* Check for an unconditional ELSE clause. */
395 if (!code->expr)
396 return gfc_trans_code (code->next);
398 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
399 gfc_init_se (&if_se, NULL);
400 gfc_start_block (&if_se.pre);
402 /* Calculate the IF condition expression. */
403 gfc_conv_expr_val (&if_se, code->expr);
405 /* Translate the THEN clause. */
406 stmt = gfc_trans_code (code->next);
408 /* Translate the ELSE clause. */
409 if (code->block)
410 elsestmt = gfc_trans_if_1 (code->block);
411 else
412 elsestmt = build_empty_stmt ();
414 /* Build the condition expression and add it to the condition block. */
415 stmt = build3_v (COND_EXPR, if_se.expr, stmt, elsestmt);
417 gfc_add_expr_to_block (&if_se.pre, stmt);
419 /* Finish off this statement. */
420 return gfc_finish_block (&if_se.pre);
423 tree
424 gfc_trans_if (gfc_code * code)
426 /* Ignore the top EXEC_IF, it only announces an IF construct. The
427 actual code we must translate is in code->block. */
429 return gfc_trans_if_1 (code->block);
433 /* Translage an arithmetic IF expression.
435 IF (cond) label1, label2, label3 translates to
437 if (cond <= 0)
439 if (cond < 0)
440 goto label1;
441 else // cond == 0
442 goto label2;
444 else // cond > 0
445 goto label3;
448 tree
449 gfc_trans_arithmetic_if (gfc_code * code)
451 gfc_se se;
452 tree tmp;
453 tree branch1;
454 tree branch2;
455 tree zero;
457 /* Start a new block. */
458 gfc_init_se (&se, NULL);
459 gfc_start_block (&se.pre);
461 /* Pre-evaluate COND. */
462 gfc_conv_expr_val (&se, code->expr);
464 /* Build something to compare with. */
465 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
467 /* If (cond < 0) take branch1 else take branch2.
468 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
469 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
470 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
472 tmp = build2 (LT_EXPR, boolean_type_node, se.expr, zero);
473 branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
475 /* if (cond <= 0) take branch1 else take branch2. */
476 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
477 tmp = build2 (LE_EXPR, boolean_type_node, se.expr, zero);
478 branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
480 /* Append the COND_EXPR to the evaluation of COND, and return. */
481 gfc_add_expr_to_block (&se.pre, branch1);
482 return gfc_finish_block (&se.pre);
486 /* Translate the simple DO construct. This is where the loop variable has
487 integer type and step +-1. We can't use this in the general case
488 because integer overflow and floating point errors could give incorrect
489 results.
490 We translate a do loop from:
492 DO dovar = from, to, step
493 body
494 END DO
498 [Evaluate loop bounds and step]
499 dovar = from;
500 if ((step > 0) ? (dovar <= to) : (dovar => to))
502 for (;;)
504 body;
505 cycle_label:
506 cond = (dovar == to);
507 dovar += step;
508 if (cond) goto end_label;
511 end_label:
513 This helps the optimizers by avoiding the extra induction variable
514 used in the general case. */
516 static tree
517 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
518 tree from, tree to, tree step)
520 stmtblock_t body;
521 tree type;
522 tree cond;
523 tree tmp;
524 tree cycle_label;
525 tree exit_label;
527 type = TREE_TYPE (dovar);
529 /* Initialize the DO variable: dovar = from. */
530 gfc_add_modify_expr (pblock, dovar, from);
532 /* Cycle and exit statements are implemented with gotos. */
533 cycle_label = gfc_build_label_decl (NULL_TREE);
534 exit_label = gfc_build_label_decl (NULL_TREE);
536 /* Put the labels where they can be found later. See gfc_trans_do(). */
537 code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
539 /* Loop body. */
540 gfc_start_block (&body);
542 /* Main loop body. */
543 tmp = gfc_trans_code (code->block->next);
544 gfc_add_expr_to_block (&body, tmp);
546 /* Label for cycle statements (if needed). */
547 if (TREE_USED (cycle_label))
549 tmp = build1_v (LABEL_EXPR, cycle_label);
550 gfc_add_expr_to_block (&body, tmp);
553 /* Evaluate the loop condition. */
554 cond = build2 (EQ_EXPR, boolean_type_node, dovar, to);
555 cond = gfc_evaluate_now (cond, &body);
557 /* Increment the loop variable. */
558 tmp = build2 (PLUS_EXPR, type, dovar, step);
559 gfc_add_modify_expr (&body, dovar, tmp);
561 /* The loop exit. */
562 tmp = build1_v (GOTO_EXPR, exit_label);
563 TREE_USED (exit_label) = 1;
564 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
565 gfc_add_expr_to_block (&body, tmp);
567 /* Finish the loop body. */
568 tmp = gfc_finish_block (&body);
569 tmp = build1_v (LOOP_EXPR, tmp);
571 /* Only execute the loop if the number of iterations is positive. */
572 if (tree_int_cst_sgn (step) > 0)
573 cond = fold (build2 (LE_EXPR, boolean_type_node, dovar, to));
574 else
575 cond = fold (build2 (GE_EXPR, boolean_type_node, dovar, to));
576 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
577 gfc_add_expr_to_block (pblock, tmp);
579 /* Add the exit label. */
580 tmp = build1_v (LABEL_EXPR, exit_label);
581 gfc_add_expr_to_block (pblock, tmp);
583 return gfc_finish_block (pblock);
586 /* Translate the DO construct. This obviously is one of the most
587 important ones to get right with any compiler, but especially
588 so for Fortran.
590 We special case some loop forms as described in gfc_trans_simple_do.
591 For other cases we implement them with a separate loop count,
592 as described in the standard.
594 We translate a do loop from:
596 DO dovar = from, to, step
597 body
598 END DO
602 [evaluate loop bounds and step]
603 count = to + step - from;
604 dovar = from;
605 for (;;)
607 body;
608 cycle_label:
609 dovar += step
610 count--;
611 if (count <=0) goto exit_label;
613 exit_label:
615 TODO: Large loop counts
616 The code above assumes the loop count fits into a signed integer kind,
617 i.e. Does not work for loop counts > 2^31 for integer(kind=4) variables
618 We must support the full range. */
620 tree
621 gfc_trans_do (gfc_code * code)
623 gfc_se se;
624 tree dovar;
625 tree from;
626 tree to;
627 tree step;
628 tree count;
629 tree count_one;
630 tree type;
631 tree cond;
632 tree cycle_label;
633 tree exit_label;
634 tree tmp;
635 stmtblock_t block;
636 stmtblock_t body;
638 gfc_start_block (&block);
640 /* Evaluate all the expressions in the iterator. */
641 gfc_init_se (&se, NULL);
642 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
643 gfc_add_block_to_block (&block, &se.pre);
644 dovar = se.expr;
645 type = TREE_TYPE (dovar);
647 gfc_init_se (&se, NULL);
648 gfc_conv_expr_val (&se, code->ext.iterator->start);
649 gfc_add_block_to_block (&block, &se.pre);
650 from = gfc_evaluate_now (se.expr, &block);
652 gfc_init_se (&se, NULL);
653 gfc_conv_expr_val (&se, code->ext.iterator->end);
654 gfc_add_block_to_block (&block, &se.pre);
655 to = gfc_evaluate_now (se.expr, &block);
657 gfc_init_se (&se, NULL);
658 gfc_conv_expr_val (&se, code->ext.iterator->step);
659 gfc_add_block_to_block (&block, &se.pre);
660 step = gfc_evaluate_now (se.expr, &block);
662 /* Special case simple loops. */
663 if (TREE_CODE (type) == INTEGER_TYPE
664 && (integer_onep (step)
665 || tree_int_cst_equal (step, integer_minus_one_node)))
666 return gfc_trans_simple_do (code, &block, dovar, from, to, step);
668 /* Initialize loop count. This code is executed before we enter the
669 loop body. We generate: count = (to + step - from) / step. */
671 tmp = fold (build2 (MINUS_EXPR, type, step, from));
672 tmp = fold (build2 (PLUS_EXPR, type, to, tmp));
673 if (TREE_CODE (type) == INTEGER_TYPE)
675 tmp = fold (build2 (TRUNC_DIV_EXPR, type, tmp, step));
676 count = gfc_create_var (type, "count");
678 else
680 /* TODO: We could use the same width as the real type.
681 This would probably cause more problems that it solves
682 when we implement "long double" types. */
683 tmp = fold (build2 (RDIV_EXPR, type, tmp, step));
684 tmp = fold (build1 (FIX_TRUNC_EXPR, gfc_array_index_type, tmp));
685 count = gfc_create_var (gfc_array_index_type, "count");
687 gfc_add_modify_expr (&block, count, tmp);
689 count_one = convert (TREE_TYPE (count), integer_one_node);
691 /* Initialize the DO variable: dovar = from. */
692 gfc_add_modify_expr (&block, dovar, from);
694 /* Loop body. */
695 gfc_start_block (&body);
697 /* Cycle and exit statements are implemented with gotos. */
698 cycle_label = gfc_build_label_decl (NULL_TREE);
699 exit_label = gfc_build_label_decl (NULL_TREE);
701 /* Start with the loop condition. Loop until count <= 0. */
702 cond = build2 (LE_EXPR, boolean_type_node, count,
703 convert (TREE_TYPE (count), integer_zero_node));
704 tmp = build1_v (GOTO_EXPR, exit_label);
705 TREE_USED (exit_label) = 1;
706 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
707 gfc_add_expr_to_block (&body, tmp);
709 /* Put these labels where they can be found later. We put the
710 labels in a TREE_LIST node (because TREE_CHAIN is already
711 used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
712 label in TREE_VALUE (backend_decl). */
714 code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
716 /* Main loop body. */
717 tmp = gfc_trans_code (code->block->next);
718 gfc_add_expr_to_block (&body, tmp);
720 /* Label for cycle statements (if needed). */
721 if (TREE_USED (cycle_label))
723 tmp = build1_v (LABEL_EXPR, cycle_label);
724 gfc_add_expr_to_block (&body, tmp);
727 /* Increment the loop variable. */
728 tmp = build2 (PLUS_EXPR, type, dovar, step);
729 gfc_add_modify_expr (&body, dovar, tmp);
731 /* Decrement the loop count. */
732 tmp = build2 (MINUS_EXPR, TREE_TYPE (count), count, count_one);
733 gfc_add_modify_expr (&body, count, tmp);
735 /* End of loop body. */
736 tmp = gfc_finish_block (&body);
738 /* The for loop itself. */
739 tmp = build1_v (LOOP_EXPR, tmp);
740 gfc_add_expr_to_block (&block, tmp);
742 /* Add the exit label. */
743 tmp = build1_v (LABEL_EXPR, exit_label);
744 gfc_add_expr_to_block (&block, tmp);
746 return gfc_finish_block (&block);
750 /* Translate the DO WHILE construct.
752 We translate
754 DO WHILE (cond)
755 body
756 END DO
760 for ( ; ; )
762 pre_cond;
763 if (! cond) goto exit_label;
764 body;
765 cycle_label:
767 exit_label:
769 Because the evaluation of the exit condition `cond' may have side
770 effects, we can't do much for empty loop bodies. The backend optimizers
771 should be smart enough to eliminate any dead loops. */
773 tree
774 gfc_trans_do_while (gfc_code * code)
776 gfc_se cond;
777 tree tmp;
778 tree cycle_label;
779 tree exit_label;
780 stmtblock_t block;
782 /* Everything we build here is part of the loop body. */
783 gfc_start_block (&block);
785 /* Cycle and exit statements are implemented with gotos. */
786 cycle_label = gfc_build_label_decl (NULL_TREE);
787 exit_label = gfc_build_label_decl (NULL_TREE);
789 /* Put the labels where they can be found later. See gfc_trans_do(). */
790 code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
792 /* Create a GIMPLE version of the exit condition. */
793 gfc_init_se (&cond, NULL);
794 gfc_conv_expr_val (&cond, code->expr);
795 gfc_add_block_to_block (&block, &cond.pre);
796 cond.expr = fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, cond.expr));
798 /* Build "IF (! cond) GOTO exit_label". */
799 tmp = build1_v (GOTO_EXPR, exit_label);
800 TREE_USED (exit_label) = 1;
801 tmp = build3_v (COND_EXPR, cond.expr, tmp, build_empty_stmt ());
802 gfc_add_expr_to_block (&block, tmp);
804 /* The main body of the loop. */
805 tmp = gfc_trans_code (code->block->next);
806 gfc_add_expr_to_block (&block, tmp);
808 /* Label for cycle statements (if needed). */
809 if (TREE_USED (cycle_label))
811 tmp = build1_v (LABEL_EXPR, cycle_label);
812 gfc_add_expr_to_block (&block, tmp);
815 /* End of loop body. */
816 tmp = gfc_finish_block (&block);
818 gfc_init_block (&block);
819 /* Build the loop. */
820 tmp = build1_v (LOOP_EXPR, tmp);
821 gfc_add_expr_to_block (&block, tmp);
823 /* Add the exit label. */
824 tmp = build1_v (LABEL_EXPR, exit_label);
825 gfc_add_expr_to_block (&block, tmp);
827 return gfc_finish_block (&block);
831 /* Translate the SELECT CASE construct for INTEGER case expressions,
832 without killing all potential optimizations. The problem is that
833 Fortran allows unbounded cases, but the back-end does not, so we
834 need to intercept those before we enter the equivalent SWITCH_EXPR
835 we can build.
837 For example, we translate this,
839 SELECT CASE (expr)
840 CASE (:100,101,105:115)
841 block_1
842 CASE (190:199,200:)
843 block_2
844 CASE (300)
845 block_3
846 CASE DEFAULT
847 block_4
848 END SELECT
850 to the GENERIC equivalent,
852 switch (expr)
854 case (minimum value for typeof(expr) ... 100:
855 case 101:
856 case 105 ... 114:
857 block1:
858 goto end_label;
860 case 200 ... (maximum value for typeof(expr):
861 case 190 ... 199:
862 block2;
863 goto end_label;
865 case 300:
866 block_3;
867 goto end_label;
869 default:
870 block_4;
871 goto end_label;
874 end_label: */
876 static tree
877 gfc_trans_integer_select (gfc_code * code)
879 gfc_code *c;
880 gfc_case *cp;
881 tree end_label;
882 tree tmp;
883 gfc_se se;
884 stmtblock_t block;
885 stmtblock_t body;
887 gfc_start_block (&block);
889 /* Calculate the switch expression. */
890 gfc_init_se (&se, NULL);
891 gfc_conv_expr_val (&se, code->expr);
892 gfc_add_block_to_block (&block, &se.pre);
894 end_label = gfc_build_label_decl (NULL_TREE);
896 gfc_init_block (&body);
898 for (c = code->block; c; c = c->block)
900 for (cp = c->ext.case_list; cp; cp = cp->next)
902 tree low, high;
903 tree label;
905 /* Assume it's the default case. */
906 low = high = NULL_TREE;
908 if (cp->low)
910 low = gfc_conv_constant_to_tree (cp->low);
912 /* If there's only a lower bound, set the high bound to the
913 maximum value of the case expression. */
914 if (!cp->high)
915 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
918 if (cp->high)
920 /* Three cases are possible here:
922 1) There is no lower bound, e.g. CASE (:N).
923 2) There is a lower bound .NE. high bound, that is
924 a case range, e.g. CASE (N:M) where M>N (we make
925 sure that M>N during type resolution).
926 3) There is a lower bound, and it has the same value
927 as the high bound, e.g. CASE (N:N). This is our
928 internal representation of CASE(N).
930 In the first and second case, we need to set a value for
931 high. In the thirth case, we don't because the GCC middle
932 end represents a single case value by just letting high be
933 a NULL_TREE. We can't do that because we need to be able
934 to represent unbounded cases. */
936 if (!cp->low
937 || (cp->low
938 && mpz_cmp (cp->low->value.integer,
939 cp->high->value.integer) != 0))
940 high = gfc_conv_constant_to_tree (cp->high);
942 /* Unbounded case. */
943 if (!cp->low)
944 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
947 /* Build a label. */
948 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
949 DECL_CONTEXT (label) = current_function_decl;
951 /* Add this case label.
952 Add parameter 'label', make it match GCC backend. */
953 tmp = build3 (CASE_LABEL_EXPR, void_type_node, low, high, label);
954 gfc_add_expr_to_block (&body, tmp);
957 /* Add the statements for this case. */
958 tmp = gfc_trans_code (c->next);
959 gfc_add_expr_to_block (&body, tmp);
961 /* Break to the end of the construct. */
962 tmp = build1_v (GOTO_EXPR, end_label);
963 gfc_add_expr_to_block (&body, tmp);
966 tmp = gfc_finish_block (&body);
967 tmp = build3_v (SWITCH_EXPR, se.expr, tmp, NULL_TREE);
968 gfc_add_expr_to_block (&block, tmp);
970 tmp = build1_v (LABEL_EXPR, end_label);
971 gfc_add_expr_to_block (&block, tmp);
973 return gfc_finish_block (&block);
977 /* Translate the SELECT CASE construct for LOGICAL case expressions.
979 There are only two cases possible here, even though the standard
980 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
981 .FALSE., and DEFAULT.
983 We never generate more than two blocks here. Instead, we always
984 try to eliminate the DEFAULT case. This way, we can translate this
985 kind of SELECT construct to a simple
987 if {} else {};
989 expression in GENERIC. */
991 static tree
992 gfc_trans_logical_select (gfc_code * code)
994 gfc_code *c;
995 gfc_code *t, *f, *d;
996 gfc_case *cp;
997 gfc_se se;
998 stmtblock_t block;
1000 /* Assume we don't have any cases at all. */
1001 t = f = d = NULL;
1003 /* Now see which ones we actually do have. We can have at most two
1004 cases in a single case list: one for .TRUE. and one for .FALSE.
1005 The default case is always separate. If the cases for .TRUE. and
1006 .FALSE. are in the same case list, the block for that case list
1007 always executed, and we don't generate code a COND_EXPR. */
1008 for (c = code->block; c; c = c->block)
1010 for (cp = c->ext.case_list; cp; cp = cp->next)
1012 if (cp->low)
1014 if (cp->low->value.logical == 0) /* .FALSE. */
1015 f = c;
1016 else /* if (cp->value.logical != 0), thus .TRUE. */
1017 t = c;
1019 else
1020 d = c;
1024 /* Start a new block. */
1025 gfc_start_block (&block);
1027 /* Calculate the switch expression. We always need to do this
1028 because it may have side effects. */
1029 gfc_init_se (&se, NULL);
1030 gfc_conv_expr_val (&se, code->expr);
1031 gfc_add_block_to_block (&block, &se.pre);
1033 if (t == f && t != NULL)
1035 /* Cases for .TRUE. and .FALSE. are in the same block. Just
1036 translate the code for these cases, append it to the current
1037 block. */
1038 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
1040 else
1042 tree true_tree, false_tree;
1044 true_tree = build_empty_stmt ();
1045 false_tree = build_empty_stmt ();
1047 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
1048 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
1049 make the missing case the default case. */
1050 if (t != NULL && f != NULL)
1051 d = NULL;
1052 else if (d != NULL)
1054 if (t == NULL)
1055 t = d;
1056 else
1057 f = d;
1060 /* Translate the code for each of these blocks, and append it to
1061 the current block. */
1062 if (t != NULL)
1063 true_tree = gfc_trans_code (t->next);
1065 if (f != NULL)
1066 false_tree = gfc_trans_code (f->next);
1068 gfc_add_expr_to_block (&block, build3_v (COND_EXPR, se.expr,
1069 true_tree, false_tree));
1072 return gfc_finish_block (&block);
1076 /* Translate the SELECT CASE construct for CHARACTER case expressions.
1077 Instead of generating compares and jumps, it is far simpler to
1078 generate a data structure describing the cases in order and call a
1079 library subroutine that locates the right case.
1080 This is particularly true because this is the only case where we
1081 might have to dispose of a temporary.
1082 The library subroutine returns a pointer to jump to or NULL if no
1083 branches are to be taken. */
1085 static tree
1086 gfc_trans_character_select (gfc_code *code)
1088 tree init, node, end_label, tmp, type, args, *labels;
1089 stmtblock_t block, body;
1090 gfc_case *cp, *d;
1091 gfc_code *c;
1092 gfc_se se;
1093 int i, n;
1095 static tree select_struct;
1096 static tree ss_string1, ss_string1_len;
1097 static tree ss_string2, ss_string2_len;
1098 static tree ss_target;
1100 if (select_struct == NULL)
1102 tree gfc_int4_type_node = gfc_get_int_type (4);
1104 select_struct = make_node (RECORD_TYPE);
1105 TYPE_NAME (select_struct) = get_identifier ("_jump_struct");
1107 #undef ADD_FIELD
1108 #define ADD_FIELD(NAME, TYPE) \
1109 ss_##NAME = gfc_add_field_to_struct \
1110 (&(TYPE_FIELDS (select_struct)), select_struct, \
1111 get_identifier (stringize(NAME)), TYPE)
1113 ADD_FIELD (string1, pchar_type_node);
1114 ADD_FIELD (string1_len, gfc_int4_type_node);
1116 ADD_FIELD (string2, pchar_type_node);
1117 ADD_FIELD (string2_len, gfc_int4_type_node);
1119 ADD_FIELD (target, pvoid_type_node);
1120 #undef ADD_FIELD
1122 gfc_finish_type (select_struct);
1125 cp = code->block->ext.case_list;
1126 while (cp->left != NULL)
1127 cp = cp->left;
1129 n = 0;
1130 for (d = cp; d; d = d->right)
1131 d->n = n++;
1133 if (n != 0)
1134 labels = gfc_getmem (n * sizeof (tree));
1135 else
1136 labels = NULL;
1138 for(i = 0; i < n; i++)
1140 labels[i] = gfc_build_label_decl (NULL_TREE);
1141 TREE_USED (labels[i]) = 1;
1142 /* TODO: The gimplifier should do this for us, but it has
1143 inadequacies when dealing with static initializers. */
1144 FORCED_LABEL (labels[i]) = 1;
1147 end_label = gfc_build_label_decl (NULL_TREE);
1149 /* Generate the body */
1150 gfc_start_block (&block);
1151 gfc_init_block (&body);
1153 for (c = code->block; c; c = c->block)
1155 for (d = c->ext.case_list; d; d = d->next)
1157 tmp = build1_v (LABEL_EXPR, labels[d->n]);
1158 gfc_add_expr_to_block (&body, tmp);
1161 tmp = gfc_trans_code (c->next);
1162 gfc_add_expr_to_block (&body, tmp);
1164 tmp = build1_v (GOTO_EXPR, end_label);
1165 gfc_add_expr_to_block (&body, tmp);
1168 /* Generate the structure describing the branches */
1169 init = NULL_TREE;
1170 i = 0;
1172 for(d = cp; d; d = d->right, i++)
1174 node = NULL_TREE;
1176 gfc_init_se (&se, NULL);
1178 if (d->low == NULL)
1180 node = tree_cons (ss_string1, null_pointer_node, node);
1181 node = tree_cons (ss_string1_len, integer_zero_node, node);
1183 else
1185 gfc_conv_expr_reference (&se, d->low);
1187 node = tree_cons (ss_string1, se.expr, node);
1188 node = tree_cons (ss_string1_len, se.string_length, node);
1191 if (d->high == NULL)
1193 node = tree_cons (ss_string2, null_pointer_node, node);
1194 node = tree_cons (ss_string2_len, integer_zero_node, node);
1196 else
1198 gfc_init_se (&se, NULL);
1199 gfc_conv_expr_reference (&se, d->high);
1201 node = tree_cons (ss_string2, se.expr, node);
1202 node = tree_cons (ss_string2_len, se.string_length, node);
1205 tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
1206 node = tree_cons (ss_target, tmp, node);
1208 tmp = build1 (CONSTRUCTOR, select_struct, nreverse (node));
1209 init = tree_cons (NULL_TREE, tmp, init);
1212 type = build_array_type (select_struct, build_index_type
1213 (build_int_cst (NULL_TREE, n - 1)));
1215 init = build1 (CONSTRUCTOR, type, nreverse(init));
1216 TREE_CONSTANT (init) = 1;
1217 TREE_INVARIANT (init) = 1;
1218 TREE_STATIC (init) = 1;
1219 /* Create a static variable to hold the jump table. */
1220 tmp = gfc_create_var (type, "jumptable");
1221 TREE_CONSTANT (tmp) = 1;
1222 TREE_INVARIANT (tmp) = 1;
1223 TREE_STATIC (tmp) = 1;
1224 DECL_INITIAL (tmp) = init;
1225 init = tmp;
1227 /* Build an argument list for the library call */
1228 init = gfc_build_addr_expr (pvoid_type_node, init);
1229 args = gfc_chainon_list (NULL_TREE, init);
1231 tmp = build_int_cst (NULL_TREE, n);
1232 args = gfc_chainon_list (args, tmp);
1234 tmp = gfc_build_addr_expr (pvoid_type_node, end_label);
1235 args = gfc_chainon_list (args, tmp);
1237 gfc_init_se (&se, NULL);
1238 gfc_conv_expr_reference (&se, code->expr);
1240 args = gfc_chainon_list (args, se.expr);
1241 args = gfc_chainon_list (args, se.string_length);
1243 gfc_add_block_to_block (&block, &se.pre);
1245 tmp = gfc_build_function_call (gfor_fndecl_select_string, args);
1246 tmp = build1 (GOTO_EXPR, void_type_node, tmp);
1247 gfc_add_expr_to_block (&block, tmp);
1249 tmp = gfc_finish_block (&body);
1250 gfc_add_expr_to_block (&block, tmp);
1251 tmp = build1_v (LABEL_EXPR, end_label);
1252 gfc_add_expr_to_block (&block, tmp);
1254 if (n != 0)
1255 gfc_free (labels);
1257 return gfc_finish_block (&block);
1261 /* Translate the three variants of the SELECT CASE construct.
1263 SELECT CASEs with INTEGER case expressions can be translated to an
1264 equivalent GENERIC switch statement, and for LOGICAL case
1265 expressions we build one or two if-else compares.
1267 SELECT CASEs with CHARACTER case expressions are a whole different
1268 story, because they don't exist in GENERIC. So we sort them and
1269 do a binary search at runtime.
1271 Fortran has no BREAK statement, and it does not allow jumps from
1272 one case block to another. That makes things a lot easier for
1273 the optimizers. */
1275 tree
1276 gfc_trans_select (gfc_code * code)
1278 gcc_assert (code && code->expr);
1280 /* Empty SELECT constructs are legal. */
1281 if (code->block == NULL)
1282 return build_empty_stmt ();
1284 /* Select the correct translation function. */
1285 switch (code->expr->ts.type)
1287 case BT_LOGICAL: return gfc_trans_logical_select (code);
1288 case BT_INTEGER: return gfc_trans_integer_select (code);
1289 case BT_CHARACTER: return gfc_trans_character_select (code);
1290 default:
1291 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
1292 /* Not reached */
1297 /* Generate the loops for a FORALL block. The normal loop format:
1298 count = (end - start + step) / step
1299 loopvar = start
1300 while (1)
1302 if (count <=0 )
1303 goto end_of_loop
1304 <body>
1305 loopvar += step
1306 count --
1308 end_of_loop: */
1310 static tree
1311 gfc_trans_forall_loop (forall_info *forall_tmp, int nvar, tree body, int mask_flag)
1313 int n;
1314 tree tmp;
1315 tree cond;
1316 stmtblock_t block;
1317 tree exit_label;
1318 tree count;
1319 tree var, start, end, step, mask, maskindex;
1320 iter_info *iter;
1322 iter = forall_tmp->this_loop;
1323 for (n = 0; n < nvar; n++)
1325 var = iter->var;
1326 start = iter->start;
1327 end = iter->end;
1328 step = iter->step;
1330 exit_label = gfc_build_label_decl (NULL_TREE);
1331 TREE_USED (exit_label) = 1;
1333 /* The loop counter. */
1334 count = gfc_create_var (TREE_TYPE (var), "count");
1336 /* The body of the loop. */
1337 gfc_init_block (&block);
1339 /* The exit condition. */
1340 cond = build2 (LE_EXPR, boolean_type_node, count, integer_zero_node);
1341 tmp = build1_v (GOTO_EXPR, exit_label);
1342 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1343 gfc_add_expr_to_block (&block, tmp);
1345 /* The main loop body. */
1346 gfc_add_expr_to_block (&block, body);
1348 /* Increment the loop variable. */
1349 tmp = build2 (PLUS_EXPR, TREE_TYPE (var), var, step);
1350 gfc_add_modify_expr (&block, var, tmp);
1352 /* Advance to the next mask element. */
1353 if (mask_flag)
1355 mask = forall_tmp->mask;
1356 maskindex = forall_tmp->maskindex;
1357 if (mask)
1359 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
1360 maskindex, gfc_index_one_node);
1361 gfc_add_modify_expr (&block, maskindex, tmp);
1364 /* Decrement the loop counter. */
1365 tmp = build2 (MINUS_EXPR, TREE_TYPE (var), count, gfc_index_one_node);
1366 gfc_add_modify_expr (&block, count, tmp);
1368 body = gfc_finish_block (&block);
1370 /* Loop var initialization. */
1371 gfc_init_block (&block);
1372 gfc_add_modify_expr (&block, var, start);
1374 /* Initialize the loop counter. */
1375 tmp = fold (build2 (MINUS_EXPR, TREE_TYPE (var), step, start));
1376 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (var), end, tmp));
1377 tmp = fold (build2 (TRUNC_DIV_EXPR, TREE_TYPE (var), tmp, step));
1378 gfc_add_modify_expr (&block, count, tmp);
1380 /* The loop expression. */
1381 tmp = build1_v (LOOP_EXPR, body);
1382 gfc_add_expr_to_block (&block, tmp);
1384 /* The exit label. */
1385 tmp = build1_v (LABEL_EXPR, exit_label);
1386 gfc_add_expr_to_block (&block, tmp);
1388 body = gfc_finish_block (&block);
1389 iter = iter->next;
1391 return body;
1395 /* Generate the body and loops according to MASK_FLAG and NEST_FLAG.
1396 if MASK_FLAG is nonzero, the body is controlled by maskes in forall
1397 nest, otherwise, the body is not controlled by maskes.
1398 if NEST_FLAG is nonzero, generate loops for nested forall, otherwise,
1399 only generate loops for the current forall level. */
1401 static tree
1402 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
1403 int mask_flag, int nest_flag)
1405 tree tmp;
1406 int nvar;
1407 forall_info *forall_tmp;
1408 tree pmask, mask, maskindex;
1410 forall_tmp = nested_forall_info;
1411 /* Generate loops for nested forall. */
1412 if (nest_flag)
1414 while (forall_tmp->next_nest != NULL)
1415 forall_tmp = forall_tmp->next_nest;
1416 while (forall_tmp != NULL)
1418 /* Generate body with masks' control. */
1419 if (mask_flag)
1421 pmask = forall_tmp->pmask;
1422 mask = forall_tmp->mask;
1423 maskindex = forall_tmp->maskindex;
1425 if (mask)
1427 /* If a mask was specified make the assignment conditional. */
1428 if (pmask)
1429 tmp = gfc_build_indirect_ref (mask);
1430 else
1431 tmp = mask;
1432 tmp = gfc_build_array_ref (tmp, maskindex);
1434 body = build3_v (COND_EXPR, tmp, body, build_empty_stmt ());
1437 nvar = forall_tmp->nvar;
1438 body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1439 forall_tmp = forall_tmp->outer;
1442 else
1444 nvar = forall_tmp->nvar;
1445 body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1448 return body;
1452 /* Allocate data for holding a temporary array. Returns either a local
1453 temporary array or a pointer variable. */
1455 static tree
1456 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
1457 tree elem_type)
1459 tree tmpvar;
1460 tree type;
1461 tree tmp;
1462 tree args;
1464 if (INTEGER_CST_P (size))
1466 tmp = fold (build2 (MINUS_EXPR, gfc_array_index_type, size,
1467 gfc_index_one_node));
1469 else
1470 tmp = NULL_TREE;
1472 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1473 type = build_array_type (elem_type, type);
1474 if (gfc_can_put_var_on_stack (bytesize))
1476 gcc_assert (INTEGER_CST_P (size));
1477 tmpvar = gfc_create_var (type, "temp");
1478 *pdata = NULL_TREE;
1480 else
1482 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
1483 *pdata = convert (pvoid_type_node, tmpvar);
1485 args = gfc_chainon_list (NULL_TREE, bytesize);
1486 if (gfc_index_integer_kind == 4)
1487 tmp = gfor_fndecl_internal_malloc;
1488 else if (gfc_index_integer_kind == 8)
1489 tmp = gfor_fndecl_internal_malloc64;
1490 else
1491 gcc_unreachable ();
1492 tmp = gfc_build_function_call (tmp, args);
1493 tmp = convert (TREE_TYPE (tmpvar), tmp);
1494 gfc_add_modify_expr (pblock, tmpvar, tmp);
1496 return tmpvar;
1500 /* Generate codes to copy the temporary to the actual lhs. */
1502 static tree
1503 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree size,
1504 tree count3, tree count1, tree count2, tree wheremask)
1506 gfc_ss *lss;
1507 gfc_se lse, rse;
1508 stmtblock_t block, body;
1509 gfc_loopinfo loop1;
1510 tree tmp, tmp2;
1511 tree index;
1512 tree wheremaskexpr;
1514 /* Walk the lhs. */
1515 lss = gfc_walk_expr (expr);
1517 if (lss == gfc_ss_terminator)
1519 gfc_start_block (&block);
1521 gfc_init_se (&lse, NULL);
1523 /* Translate the expression. */
1524 gfc_conv_expr (&lse, expr);
1526 /* Form the expression for the temporary. */
1527 tmp = gfc_build_array_ref (tmp1, count1);
1529 /* Use the scalar assignment as is. */
1530 gfc_add_block_to_block (&block, &lse.pre);
1531 gfc_add_modify_expr (&block, lse.expr, tmp);
1532 gfc_add_block_to_block (&block, &lse.post);
1534 /* Increment the count1. */
1535 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (count1), count1, size));
1536 gfc_add_modify_expr (&block, count1, tmp);
1537 tmp = gfc_finish_block (&block);
1539 else
1541 gfc_start_block (&block);
1543 gfc_init_loopinfo (&loop1);
1544 gfc_init_se (&rse, NULL);
1545 gfc_init_se (&lse, NULL);
1547 /* Associate the lss with the loop. */
1548 gfc_add_ss_to_loop (&loop1, lss);
1550 /* Calculate the bounds of the scalarization. */
1551 gfc_conv_ss_startstride (&loop1);
1552 /* Setup the scalarizing loops. */
1553 gfc_conv_loop_setup (&loop1);
1555 gfc_mark_ss_chain_used (lss, 1);
1556 /* Initialize count2. */
1557 gfc_add_modify_expr (&block, count2, gfc_index_zero_node);
1559 /* Start the scalarized loop body. */
1560 gfc_start_scalarized_body (&loop1, &body);
1562 /* Setup the gfc_se structures. */
1563 gfc_copy_loopinfo_to_se (&lse, &loop1);
1564 lse.ss = lss;
1566 /* Form the expression of the temporary. */
1567 if (lss != gfc_ss_terminator)
1569 index = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1570 count1, count2));
1571 rse.expr = gfc_build_array_ref (tmp1, index);
1573 /* Translate expr. */
1574 gfc_conv_expr (&lse, expr);
1576 /* Use the scalar assignment. */
1577 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
1579 /* Form the mask expression according to the mask tree list. */
1580 if (wheremask)
1582 tmp2 = wheremask;
1583 if (tmp2 != NULL)
1584 wheremaskexpr = gfc_build_array_ref (tmp2, count3);
1585 tmp2 = TREE_CHAIN (tmp2);
1586 while (tmp2)
1588 tmp1 = gfc_build_array_ref (tmp2, count3);
1589 wheremaskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
1590 wheremaskexpr, tmp1);
1591 tmp2 = TREE_CHAIN (tmp2);
1593 tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1596 gfc_add_expr_to_block (&body, tmp);
1598 /* Increment count2. */
1599 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1600 count2, gfc_index_one_node));
1601 gfc_add_modify_expr (&body, count2, tmp);
1603 /* Increment count3. */
1604 if (count3)
1606 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1607 count3, gfc_index_one_node));
1608 gfc_add_modify_expr (&body, count3, tmp);
1611 /* Generate the copying loops. */
1612 gfc_trans_scalarizing_loops (&loop1, &body);
1613 gfc_add_block_to_block (&block, &loop1.pre);
1614 gfc_add_block_to_block (&block, &loop1.post);
1615 gfc_cleanup_loop (&loop1);
1617 /* Increment count1. */
1618 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (count1), count1, size));
1619 gfc_add_modify_expr (&block, count1, tmp);
1620 tmp = gfc_finish_block (&block);
1622 return tmp;
1626 /* Generate codes to copy rhs to the temporary. TMP1 is the address of temporary
1627 LSS and RSS are formed in function compute_inner_temp_size(), and should
1628 not be freed. */
1630 static tree
1631 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree size,
1632 tree count3, tree count1, tree count2,
1633 gfc_ss *lss, gfc_ss *rss, tree wheremask)
1635 stmtblock_t block, body1;
1636 gfc_loopinfo loop;
1637 gfc_se lse;
1638 gfc_se rse;
1639 tree tmp, tmp2, index;
1640 tree wheremaskexpr;
1642 gfc_start_block (&block);
1644 gfc_init_se (&rse, NULL);
1645 gfc_init_se (&lse, NULL);
1647 if (lss == gfc_ss_terminator)
1649 gfc_init_block (&body1);
1650 gfc_conv_expr (&rse, expr2);
1651 lse.expr = gfc_build_array_ref (tmp1, count1);
1653 else
1655 /* Initialize count2. */
1656 gfc_add_modify_expr (&block, count2, gfc_index_zero_node);
1658 /* Initialize the loop. */
1659 gfc_init_loopinfo (&loop);
1661 /* We may need LSS to determine the shape of the expression. */
1662 gfc_add_ss_to_loop (&loop, lss);
1663 gfc_add_ss_to_loop (&loop, rss);
1665 gfc_conv_ss_startstride (&loop);
1666 gfc_conv_loop_setup (&loop);
1668 gfc_mark_ss_chain_used (rss, 1);
1669 /* Start the loop body. */
1670 gfc_start_scalarized_body (&loop, &body1);
1672 /* Translate the expression. */
1673 gfc_copy_loopinfo_to_se (&rse, &loop);
1674 rse.ss = rss;
1675 gfc_conv_expr (&rse, expr2);
1677 /* Form the expression of the temporary. */
1678 index = fold (build2 (PLUS_EXPR, gfc_array_index_type, count1, count2));
1679 lse.expr = gfc_build_array_ref (tmp1, index);
1682 /* Use the scalar assignment. */
1683 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts.type);
1685 /* Form the mask expression according to the mask tree list. */
1686 if (wheremask)
1688 tmp2 = wheremask;
1689 if (tmp2 != NULL)
1690 wheremaskexpr = gfc_build_array_ref (tmp2, count3);
1691 tmp2 = TREE_CHAIN (tmp2);
1692 while (tmp2)
1694 tmp1 = gfc_build_array_ref (tmp2, count3);
1695 wheremaskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
1696 wheremaskexpr, tmp1);
1697 tmp2 = TREE_CHAIN (tmp2);
1699 tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1702 gfc_add_expr_to_block (&body1, tmp);
1704 if (lss == gfc_ss_terminator)
1706 gfc_add_block_to_block (&block, &body1);
1708 else
1710 /* Increment count2. */
1711 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1712 count2, gfc_index_one_node));
1713 gfc_add_modify_expr (&body1, count2, tmp);
1715 /* Increment count3. */
1716 if (count3)
1718 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1719 count3, gfc_index_one_node));
1720 gfc_add_modify_expr (&body1, count3, tmp);
1723 /* Generate the copying loops. */
1724 gfc_trans_scalarizing_loops (&loop, &body1);
1726 gfc_add_block_to_block (&block, &loop.pre);
1727 gfc_add_block_to_block (&block, &loop.post);
1729 gfc_cleanup_loop (&loop);
1730 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
1731 as tree nodes in SS may not be valid in different scope. */
1733 /* Increment count1. */
1734 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (count1), count1, size));
1735 gfc_add_modify_expr (&block, count1, tmp);
1737 tmp = gfc_finish_block (&block);
1738 return tmp;
1742 /* Calculate the size of temporary needed in the assignment inside forall.
1743 LSS and RSS are filled in this function. */
1745 static tree
1746 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
1747 stmtblock_t * pblock,
1748 gfc_ss **lss, gfc_ss **rss)
1750 gfc_loopinfo loop;
1751 tree size;
1752 int i;
1753 tree tmp;
1755 *lss = gfc_walk_expr (expr1);
1756 *rss = NULL;
1758 size = gfc_index_one_node;
1759 if (*lss != gfc_ss_terminator)
1761 gfc_init_loopinfo (&loop);
1763 /* Walk the RHS of the expression. */
1764 *rss = gfc_walk_expr (expr2);
1765 if (*rss == gfc_ss_terminator)
1767 /* The rhs is scalar. Add a ss for the expression. */
1768 *rss = gfc_get_ss ();
1769 (*rss)->next = gfc_ss_terminator;
1770 (*rss)->type = GFC_SS_SCALAR;
1771 (*rss)->expr = expr2;
1774 /* Associate the SS with the loop. */
1775 gfc_add_ss_to_loop (&loop, *lss);
1776 /* We don't actually need to add the rhs at this point, but it might
1777 make guessing the loop bounds a bit easier. */
1778 gfc_add_ss_to_loop (&loop, *rss);
1780 /* We only want the shape of the expression, not rest of the junk
1781 generated by the scalarizer. */
1782 loop.array_parameter = 1;
1784 /* Calculate the bounds of the scalarization. */
1785 gfc_conv_ss_startstride (&loop);
1786 gfc_conv_loop_setup (&loop);
1788 /* Figure out how many elements we need. */
1789 for (i = 0; i < loop.dimen; i++)
1791 tmp = fold (build2 (MINUS_EXPR, gfc_array_index_type,
1792 gfc_index_one_node, loop.from[i]));
1793 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1794 tmp, loop.to[i]));
1795 size = fold (build2 (MULT_EXPR, gfc_array_index_type, size, tmp));
1797 gfc_add_block_to_block (pblock, &loop.pre);
1798 size = gfc_evaluate_now (size, pblock);
1799 gfc_add_block_to_block (pblock, &loop.post);
1801 /* TODO: write a function that cleans up a loopinfo without freeing
1802 the SS chains. Currently a NOP. */
1805 return size;
1809 /* Calculate the overall iterator number of the nested forall construct. */
1811 static tree
1812 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
1813 stmtblock_t *block)
1815 tree tmp, number;
1816 stmtblock_t body;
1818 /* TODO: optimizing the computing process. */
1819 number = gfc_create_var (gfc_array_index_type, "num");
1820 gfc_add_modify_expr (block, number, gfc_index_zero_node);
1822 gfc_start_block (&body);
1823 if (nested_forall_info)
1824 tmp = build2 (PLUS_EXPR, gfc_array_index_type, number,
1825 inner_size);
1826 else
1827 tmp = inner_size;
1828 gfc_add_modify_expr (&body, number, tmp);
1829 tmp = gfc_finish_block (&body);
1831 /* Generate loops. */
1832 if (nested_forall_info != NULL)
1833 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 0, 1);
1835 gfc_add_expr_to_block (block, tmp);
1837 return number;
1841 /* Allocate temporary for forall construct according to the information in
1842 nested_forall_info. INNER_SIZE is the size of temporary needed in the
1843 assignment inside forall. PTEMP1 is returned for space free. */
1845 static tree
1846 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
1847 tree inner_size, stmtblock_t * block,
1848 tree * ptemp1)
1850 tree unit;
1851 tree temp1;
1852 tree tmp;
1853 tree bytesize, size;
1855 /* Calculate the total size of temporary needed in forall construct. */
1856 size = compute_overall_iter_number (nested_forall_info, inner_size, block);
1858 unit = TYPE_SIZE_UNIT (type);
1859 bytesize = fold (build2 (MULT_EXPR, gfc_array_index_type, size, unit));
1861 *ptemp1 = NULL;
1862 temp1 = gfc_do_allocate (bytesize, size, ptemp1, block, type);
1864 if (*ptemp1)
1865 tmp = gfc_build_indirect_ref (temp1);
1866 else
1867 tmp = temp1;
1869 return tmp;
1873 /* Handle assignments inside forall which need temporary. */
1874 static void
1875 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2, tree wheremask,
1876 forall_info * nested_forall_info,
1877 stmtblock_t * block)
1879 tree type;
1880 tree inner_size;
1881 gfc_ss *lss, *rss;
1882 tree count, count1, count2;
1883 tree tmp, tmp1;
1884 tree ptemp1;
1885 tree mask, maskindex;
1886 forall_info *forall_tmp;
1888 /* Create vars. count1 is the current iterator number of the nested forall.
1889 count2 is the current iterator number of the inner loops needed in the
1890 assignment. */
1891 count1 = gfc_create_var (gfc_array_index_type, "count1");
1892 count2 = gfc_create_var (gfc_array_index_type, "count2");
1894 /* Count is the wheremask index. */
1895 if (wheremask)
1897 count = gfc_create_var (gfc_array_index_type, "count");
1898 gfc_add_modify_expr (block, count, gfc_index_zero_node);
1900 else
1901 count = NULL;
1903 /* Initialize count1. */
1904 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
1906 /* Calculate the size of temporary needed in the assignment. Return loop, lss
1907 and rss which are used in function generate_loop_for_rhs_to_temp(). */
1908 inner_size = compute_inner_temp_size (expr1, expr2, block, &lss, &rss);
1910 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
1911 type = gfc_typenode_for_spec (&expr1->ts);
1913 /* Allocate temporary for nested forall construct according to the
1914 information in nested_forall_info and inner_size. */
1915 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
1916 inner_size, block, &ptemp1);
1918 /* Initialize the maskindexes. */
1919 forall_tmp = nested_forall_info;
1920 while (forall_tmp != NULL)
1922 mask = forall_tmp->mask;
1923 maskindex = forall_tmp->maskindex;
1924 if (mask)
1925 gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
1926 forall_tmp = forall_tmp->next_nest;
1929 /* Generate codes to copy rhs to the temporary . */
1930 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, inner_size, count,
1931 count1, count2, lss, rss, wheremask);
1933 /* Generate body and loops according to the information in
1934 nested_forall_info. */
1935 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
1936 gfc_add_expr_to_block (block, tmp);
1938 /* Reset count1. */
1939 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
1941 /* Reset maskindexed. */
1942 forall_tmp = nested_forall_info;
1943 while (forall_tmp != NULL)
1945 mask = forall_tmp->mask;
1946 maskindex = forall_tmp->maskindex;
1947 if (mask)
1948 gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
1949 forall_tmp = forall_tmp->next_nest;
1952 /* Reset count. */
1953 if (wheremask)
1954 gfc_add_modify_expr (block, count, gfc_index_zero_node);
1956 /* Generate codes to copy the temporary to lhs. */
1957 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, inner_size, count,
1958 count1, count2, wheremask);
1960 /* Generate body and loops according to the information in
1961 nested_forall_info. */
1962 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
1963 gfc_add_expr_to_block (block, tmp);
1965 if (ptemp1)
1967 /* Free the temporary. */
1968 tmp = gfc_chainon_list (NULL_TREE, ptemp1);
1969 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
1970 gfc_add_expr_to_block (block, tmp);
1975 /* Translate pointer assignment inside FORALL which need temporary. */
1977 static void
1978 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
1979 forall_info * nested_forall_info,
1980 stmtblock_t * block)
1982 tree type;
1983 tree inner_size;
1984 gfc_ss *lss, *rss;
1985 gfc_se lse;
1986 gfc_se rse;
1987 gfc_ss_info *info;
1988 gfc_loopinfo loop;
1989 tree desc;
1990 tree parm;
1991 tree parmtype;
1992 stmtblock_t body;
1993 tree count;
1994 tree tmp, tmp1, ptemp1;
1995 tree mask, maskindex;
1996 forall_info *forall_tmp;
1998 count = gfc_create_var (gfc_array_index_type, "count");
1999 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2001 inner_size = integer_one_node;
2002 lss = gfc_walk_expr (expr1);
2003 rss = gfc_walk_expr (expr2);
2004 if (lss == gfc_ss_terminator)
2006 type = gfc_typenode_for_spec (&expr1->ts);
2007 type = build_pointer_type (type);
2009 /* Allocate temporary for nested forall construct according to the
2010 information in nested_forall_info and inner_size. */
2011 tmp1 = allocate_temp_for_forall_nest (nested_forall_info,
2012 type, inner_size, block, &ptemp1);
2013 gfc_start_block (&body);
2014 gfc_init_se (&lse, NULL);
2015 lse.expr = gfc_build_array_ref (tmp1, count);
2016 gfc_init_se (&rse, NULL);
2017 rse.want_pointer = 1;
2018 gfc_conv_expr (&rse, expr2);
2019 gfc_add_block_to_block (&body, &rse.pre);
2020 gfc_add_modify_expr (&body, lse.expr, rse.expr);
2021 gfc_add_block_to_block (&body, &rse.post);
2023 /* Increment count. */
2024 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2025 count, gfc_index_one_node));
2026 gfc_add_modify_expr (&body, count, tmp);
2028 tmp = gfc_finish_block (&body);
2030 /* Initialize the maskindexes. */
2031 forall_tmp = nested_forall_info;
2032 while (forall_tmp != NULL)
2034 mask = forall_tmp->mask;
2035 maskindex = forall_tmp->maskindex;
2036 if (mask)
2037 gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2038 forall_tmp = forall_tmp->next_nest;
2041 /* Generate body and loops according to the information in
2042 nested_forall_info. */
2043 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2044 gfc_add_expr_to_block (block, tmp);
2046 /* Reset count. */
2047 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2049 /* Reset maskindexes. */
2050 forall_tmp = nested_forall_info;
2051 while (forall_tmp != NULL)
2053 mask = forall_tmp->mask;
2054 maskindex = forall_tmp->maskindex;
2055 if (mask)
2056 gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2057 forall_tmp = forall_tmp->next_nest;
2059 gfc_start_block (&body);
2060 gfc_init_se (&lse, NULL);
2061 gfc_init_se (&rse, NULL);
2062 rse.expr = gfc_build_array_ref (tmp1, count);
2063 lse.want_pointer = 1;
2064 gfc_conv_expr (&lse, expr1);
2065 gfc_add_block_to_block (&body, &lse.pre);
2066 gfc_add_modify_expr (&body, lse.expr, rse.expr);
2067 gfc_add_block_to_block (&body, &lse.post);
2068 /* Increment count. */
2069 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2070 count, gfc_index_one_node));
2071 gfc_add_modify_expr (&body, count, tmp);
2072 tmp = gfc_finish_block (&body);
2074 /* Generate body and loops according to the information in
2075 nested_forall_info. */
2076 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2077 gfc_add_expr_to_block (block, tmp);
2079 else
2081 gfc_init_loopinfo (&loop);
2083 /* Associate the SS with the loop. */
2084 gfc_add_ss_to_loop (&loop, rss);
2086 /* Setup the scalarizing loops and bounds. */
2087 gfc_conv_ss_startstride (&loop);
2089 gfc_conv_loop_setup (&loop);
2091 info = &rss->data.info;
2092 desc = info->descriptor;
2094 /* Make a new descriptor. */
2095 parmtype = gfc_get_element_type (TREE_TYPE (desc));
2096 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
2097 loop.from, loop.to, 1);
2099 /* Allocate temporary for nested forall construct. */
2100 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
2101 inner_size, block, &ptemp1);
2102 gfc_start_block (&body);
2103 gfc_init_se (&lse, NULL);
2104 lse.expr = gfc_build_array_ref (tmp1, count);
2105 lse.direct_byref = 1;
2106 rss = gfc_walk_expr (expr2);
2107 gfc_conv_expr_descriptor (&lse, expr2, rss);
2109 gfc_add_block_to_block (&body, &lse.pre);
2110 gfc_add_block_to_block (&body, &lse.post);
2112 /* Increment count. */
2113 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2114 count, gfc_index_one_node));
2115 gfc_add_modify_expr (&body, count, tmp);
2117 tmp = gfc_finish_block (&body);
2119 /* Initialize the maskindexes. */
2120 forall_tmp = nested_forall_info;
2121 while (forall_tmp != NULL)
2123 mask = forall_tmp->mask;
2124 maskindex = forall_tmp->maskindex;
2125 if (mask)
2126 gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2127 forall_tmp = forall_tmp->next_nest;
2130 /* Generate body and loops according to the information in
2131 nested_forall_info. */
2132 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2133 gfc_add_expr_to_block (block, tmp);
2135 /* Reset count. */
2136 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2138 /* Reset maskindexes. */
2139 forall_tmp = nested_forall_info;
2140 while (forall_tmp != NULL)
2142 mask = forall_tmp->mask;
2143 maskindex = forall_tmp->maskindex;
2144 if (mask)
2145 gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2146 forall_tmp = forall_tmp->next_nest;
2148 parm = gfc_build_array_ref (tmp1, count);
2149 lss = gfc_walk_expr (expr1);
2150 gfc_init_se (&lse, NULL);
2151 gfc_conv_expr_descriptor (&lse, expr1, lss);
2152 gfc_add_modify_expr (&lse.pre, lse.expr, parm);
2153 gfc_start_block (&body);
2154 gfc_add_block_to_block (&body, &lse.pre);
2155 gfc_add_block_to_block (&body, &lse.post);
2157 /* Increment count. */
2158 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2159 count, gfc_index_one_node));
2160 gfc_add_modify_expr (&body, count, tmp);
2162 tmp = gfc_finish_block (&body);
2164 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2165 gfc_add_expr_to_block (block, tmp);
2167 /* Free the temporary. */
2168 if (ptemp1)
2170 tmp = gfc_chainon_list (NULL_TREE, ptemp1);
2171 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2172 gfc_add_expr_to_block (block, tmp);
2177 /* FORALL and WHERE statements are really nasty, especially when you nest
2178 them. All the rhs of a forall assignment must be evaluated before the
2179 actual assignments are performed. Presumably this also applies to all the
2180 assignments in an inner where statement. */
2182 /* Generate code for a FORALL statement. Any temporaries are allocated as a
2183 linear array, relying on the fact that we process in the same order in all
2184 loops.
2186 forall (i=start:end:stride; maskexpr)
2187 e<i> = f<i>
2188 g<i> = h<i>
2189 end forall
2190 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
2191 Translates to:
2192 count = ((end + 1 - start) / staride)
2193 masktmp(:) = maskexpr(:)
2195 maskindex = 0;
2196 for (i = start; i <= end; i += stride)
2198 if (masktmp[maskindex++])
2199 e<i> = f<i>
2201 maskindex = 0;
2202 for (i = start; i <= end; i += stride)
2204 if (masktmp[maskindex++])
2205 e<i> = f<i>
2208 Note that this code only works when there are no dependencies.
2209 Forall loop with array assignments and data dependencies are a real pain,
2210 because the size of the temporary cannot always be determined before the
2211 loop is executed. This problem is compounded by the presence of nested
2212 FORALL constructs.
2215 static tree
2216 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
2218 stmtblock_t block;
2219 stmtblock_t body;
2220 tree *var;
2221 tree *start;
2222 tree *end;
2223 tree *step;
2224 gfc_expr **varexpr;
2225 tree tmp;
2226 tree assign;
2227 tree size;
2228 tree bytesize;
2229 tree tmpvar;
2230 tree sizevar;
2231 tree lenvar;
2232 tree maskindex;
2233 tree mask;
2234 tree pmask;
2235 int n;
2236 int nvar;
2237 int need_temp;
2238 gfc_forall_iterator *fa;
2239 gfc_se se;
2240 gfc_code *c;
2241 gfc_saved_var *saved_vars;
2242 iter_info *this_forall, *iter_tmp;
2243 forall_info *info, *forall_tmp;
2244 temporary_list *temp;
2246 gfc_start_block (&block);
2248 n = 0;
2249 /* Count the FORALL index number. */
2250 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
2251 n++;
2252 nvar = n;
2254 /* Allocate the space for var, start, end, step, varexpr. */
2255 var = (tree *) gfc_getmem (nvar * sizeof (tree));
2256 start = (tree *) gfc_getmem (nvar * sizeof (tree));
2257 end = (tree *) gfc_getmem (nvar * sizeof (tree));
2258 step = (tree *) gfc_getmem (nvar * sizeof (tree));
2259 varexpr = (gfc_expr **) gfc_getmem (nvar * sizeof (gfc_expr *));
2260 saved_vars = (gfc_saved_var *) gfc_getmem (nvar * sizeof (gfc_saved_var));
2262 /* Allocate the space for info. */
2263 info = (forall_info *) gfc_getmem (sizeof (forall_info));
2264 n = 0;
2265 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
2267 gfc_symbol *sym = fa->var->symtree->n.sym;
2269 /* allocate space for this_forall. */
2270 this_forall = (iter_info *) gfc_getmem (sizeof (iter_info));
2272 /* Create a temporary variable for the FORALL index. */
2273 tmp = gfc_typenode_for_spec (&sym->ts);
2274 var[n] = gfc_create_var (tmp, sym->name);
2275 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
2277 /* Record it in this_forall. */
2278 this_forall->var = var[n];
2280 /* Replace the index symbol's backend_decl with the temporary decl. */
2281 sym->backend_decl = var[n];
2283 /* Work out the start, end and stride for the loop. */
2284 gfc_init_se (&se, NULL);
2285 gfc_conv_expr_val (&se, fa->start);
2286 /* Record it in this_forall. */
2287 this_forall->start = se.expr;
2288 gfc_add_block_to_block (&block, &se.pre);
2289 start[n] = se.expr;
2291 gfc_init_se (&se, NULL);
2292 gfc_conv_expr_val (&se, fa->end);
2293 /* Record it in this_forall. */
2294 this_forall->end = se.expr;
2295 gfc_make_safe_expr (&se);
2296 gfc_add_block_to_block (&block, &se.pre);
2297 end[n] = se.expr;
2299 gfc_init_se (&se, NULL);
2300 gfc_conv_expr_val (&se, fa->stride);
2301 /* Record it in this_forall. */
2302 this_forall->step = se.expr;
2303 gfc_make_safe_expr (&se);
2304 gfc_add_block_to_block (&block, &se.pre);
2305 step[n] = se.expr;
2307 /* Set the NEXT field of this_forall to NULL. */
2308 this_forall->next = NULL;
2309 /* Link this_forall to the info construct. */
2310 if (info->this_loop == NULL)
2311 info->this_loop = this_forall;
2312 else
2314 iter_tmp = info->this_loop;
2315 while (iter_tmp->next != NULL)
2316 iter_tmp = iter_tmp->next;
2317 iter_tmp->next = this_forall;
2320 n++;
2322 nvar = n;
2324 /* Work out the number of elements in the mask array. */
2325 tmpvar = NULL_TREE;
2326 lenvar = NULL_TREE;
2327 size = gfc_index_one_node;
2328 sizevar = NULL_TREE;
2330 for (n = 0; n < nvar; n++)
2332 if (lenvar && TREE_TYPE (lenvar) != TREE_TYPE (start[n]))
2333 lenvar = NULL_TREE;
2335 /* size = (end + step - start) / step. */
2336 tmp = fold (build2 (MINUS_EXPR, TREE_TYPE (start[n]),
2337 step[n], start[n]));
2338 tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (end[n]), end[n], tmp));
2340 tmp = fold (build2 (FLOOR_DIV_EXPR, TREE_TYPE (tmp), tmp, step[n]));
2341 tmp = convert (gfc_array_index_type, tmp);
2343 size = fold (build2 (MULT_EXPR, gfc_array_index_type, size, tmp));
2346 /* Record the nvar and size of current forall level. */
2347 info->nvar = nvar;
2348 info->size = size;
2350 /* Link the current forall level to nested_forall_info. */
2351 forall_tmp = nested_forall_info;
2352 if (forall_tmp == NULL)
2353 nested_forall_info = info;
2354 else
2356 while (forall_tmp->next_nest != NULL)
2357 forall_tmp = forall_tmp->next_nest;
2358 info->outer = forall_tmp;
2359 forall_tmp->next_nest = info;
2362 /* Copy the mask into a temporary variable if required.
2363 For now we assume a mask temporary is needed. */
2364 if (code->expr)
2366 /* Allocate the mask temporary. */
2367 bytesize = fold (build2 (MULT_EXPR, gfc_array_index_type, size,
2368 TYPE_SIZE_UNIT (boolean_type_node)));
2370 mask = gfc_do_allocate (bytesize, size, &pmask, &block, boolean_type_node);
2372 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
2373 /* Record them in the info structure. */
2374 info->pmask = pmask;
2375 info->mask = mask;
2376 info->maskindex = maskindex;
2378 gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2380 /* Start of mask assignment loop body. */
2381 gfc_start_block (&body);
2383 /* Evaluate the mask expression. */
2384 gfc_init_se (&se, NULL);
2385 gfc_conv_expr_val (&se, code->expr);
2386 gfc_add_block_to_block (&body, &se.pre);
2388 /* Store the mask. */
2389 se.expr = convert (boolean_type_node, se.expr);
2391 if (pmask)
2392 tmp = gfc_build_indirect_ref (mask);
2393 else
2394 tmp = mask;
2395 tmp = gfc_build_array_ref (tmp, maskindex);
2396 gfc_add_modify_expr (&body, tmp, se.expr);
2398 /* Advance to the next mask element. */
2399 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2400 maskindex, gfc_index_one_node);
2401 gfc_add_modify_expr (&body, maskindex, tmp);
2403 /* Generate the loops. */
2404 tmp = gfc_finish_block (&body);
2405 tmp = gfc_trans_nested_forall_loop (info, tmp, 0, 0);
2406 gfc_add_expr_to_block (&block, tmp);
2408 else
2410 /* No mask was specified. */
2411 maskindex = NULL_TREE;
2412 mask = pmask = NULL_TREE;
2415 c = code->block->next;
2417 /* TODO: loop merging in FORALL statements. */
2418 /* Now that we've got a copy of the mask, generate the assignment loops. */
2419 while (c)
2421 switch (c->op)
2423 case EXEC_ASSIGN:
2424 /* A scalar or array assignment. */
2425 need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
2426 /* Teporaries due to array assignment data dependencies introduce
2427 no end of problems. */
2428 if (need_temp)
2429 gfc_trans_assign_need_temp (c->expr, c->expr2, NULL,
2430 nested_forall_info, &block);
2431 else
2433 /* Use the normal assignment copying routines. */
2434 assign = gfc_trans_assignment (c->expr, c->expr2);
2436 /* Reset the mask index. */
2437 if (mask)
2438 gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2440 /* Generate body and loops. */
2441 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1, 1);
2442 gfc_add_expr_to_block (&block, tmp);
2445 break;
2447 case EXEC_WHERE:
2449 /* Translate WHERE or WHERE construct nested in FORALL. */
2450 temp = NULL;
2451 gfc_trans_where_2 (c, NULL, NULL, nested_forall_info, &block, &temp);
2453 while (temp)
2455 tree args;
2456 temporary_list *p;
2458 /* Free the temporary. */
2459 args = gfc_chainon_list (NULL_TREE, temp->temporary);
2460 tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
2461 gfc_add_expr_to_block (&block, tmp);
2463 p = temp;
2464 temp = temp->next;
2465 gfc_free (p);
2468 break;
2470 /* Pointer assignment inside FORALL. */
2471 case EXEC_POINTER_ASSIGN:
2472 need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
2473 if (need_temp)
2474 gfc_trans_pointer_assign_need_temp (c->expr, c->expr2,
2475 nested_forall_info, &block);
2476 else
2478 /* Use the normal assignment copying routines. */
2479 assign = gfc_trans_pointer_assignment (c->expr, c->expr2);
2481 /* Reset the mask index. */
2482 if (mask)
2483 gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2485 /* Generate body and loops. */
2486 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign,
2487 1, 1);
2488 gfc_add_expr_to_block (&block, tmp);
2490 break;
2492 case EXEC_FORALL:
2493 tmp = gfc_trans_forall_1 (c, nested_forall_info);
2494 gfc_add_expr_to_block (&block, tmp);
2495 break;
2497 default:
2498 gcc_unreachable ();
2501 c = c->next;
2504 /* Restore the original index variables. */
2505 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
2506 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
2508 /* Free the space for var, start, end, step, varexpr. */
2509 gfc_free (var);
2510 gfc_free (start);
2511 gfc_free (end);
2512 gfc_free (step);
2513 gfc_free (varexpr);
2514 gfc_free (saved_vars);
2516 if (pmask)
2518 /* Free the temporary for the mask. */
2519 tmp = gfc_chainon_list (NULL_TREE, pmask);
2520 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2521 gfc_add_expr_to_block (&block, tmp);
2523 if (maskindex)
2524 pushdecl (maskindex);
2526 return gfc_finish_block (&block);
2530 /* Translate the FORALL statement or construct. */
2532 tree gfc_trans_forall (gfc_code * code)
2534 return gfc_trans_forall_1 (code, NULL);
2538 /* Evaluate the WHERE mask expression, copy its value to a temporary.
2539 If the WHERE construct is nested in FORALL, compute the overall temporary
2540 needed by the WHERE mask expression multiplied by the iterator number of
2541 the nested forall.
2542 ME is the WHERE mask expression.
2543 MASK is the temporary which value is mask's value.
2544 NMASK is another temporary which value is !mask.
2545 TEMP records the temporary's address allocated in this function in order to
2546 free them outside this function.
2547 MASK, NMASK and TEMP are all OUT arguments. */
2549 static tree
2550 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
2551 tree * mask, tree * nmask, temporary_list ** temp,
2552 stmtblock_t * block)
2554 tree tmp, tmp1;
2555 gfc_ss *lss, *rss;
2556 gfc_loopinfo loop;
2557 tree ptemp1, ntmp, ptemp2;
2558 tree inner_size;
2559 stmtblock_t body, body1;
2560 gfc_se lse, rse;
2561 tree count;
2562 tree tmpexpr;
2564 gfc_init_loopinfo (&loop);
2566 /* Calculate the size of temporary needed by the mask-expr. */
2567 inner_size = compute_inner_temp_size (me, me, block, &lss, &rss);
2569 /* Allocate temporary for where mask. */
2570 tmp = allocate_temp_for_forall_nest (nested_forall_info, boolean_type_node,
2571 inner_size, block, &ptemp1);
2572 /* Record the temporary address in order to free it later. */
2573 if (ptemp1)
2575 temporary_list *tempo;
2576 tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2577 tempo->temporary = ptemp1;
2578 tempo->next = *temp;
2579 *temp = tempo;
2582 /* Allocate temporary for !mask. */
2583 ntmp = allocate_temp_for_forall_nest (nested_forall_info, boolean_type_node,
2584 inner_size, block, &ptemp2);
2585 /* Record the temporary in order to free it later. */
2586 if (ptemp2)
2588 temporary_list *tempo;
2589 tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2590 tempo->temporary = ptemp2;
2591 tempo->next = *temp;
2592 *temp = tempo;
2595 /* Variable to index the temporary. */
2596 count = gfc_create_var (gfc_array_index_type, "count");
2597 /* Initialize count. */
2598 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2600 gfc_start_block (&body);
2602 gfc_init_se (&rse, NULL);
2603 gfc_init_se (&lse, NULL);
2605 if (lss == gfc_ss_terminator)
2607 gfc_init_block (&body1);
2609 else
2611 /* Initialize the loop. */
2612 gfc_init_loopinfo (&loop);
2614 /* We may need LSS to determine the shape of the expression. */
2615 gfc_add_ss_to_loop (&loop, lss);
2616 gfc_add_ss_to_loop (&loop, rss);
2618 gfc_conv_ss_startstride (&loop);
2619 gfc_conv_loop_setup (&loop);
2621 gfc_mark_ss_chain_used (rss, 1);
2622 /* Start the loop body. */
2623 gfc_start_scalarized_body (&loop, &body1);
2625 /* Translate the expression. */
2626 gfc_copy_loopinfo_to_se (&rse, &loop);
2627 rse.ss = rss;
2628 gfc_conv_expr (&rse, me);
2630 /* Form the expression of the temporary. */
2631 lse.expr = gfc_build_array_ref (tmp, count);
2632 tmpexpr = gfc_build_array_ref (ntmp, count);
2634 /* Use the scalar assignment to fill temporary TMP. */
2635 tmp1 = gfc_trans_scalar_assign (&lse, &rse, me->ts.type);
2636 gfc_add_expr_to_block (&body1, tmp1);
2638 /* Fill temporary NTMP. */
2639 tmp1 = build1 (TRUTH_NOT_EXPR, TREE_TYPE (lse.expr), lse.expr);
2640 gfc_add_modify_expr (&body1, tmpexpr, tmp1);
2642 if (lss == gfc_ss_terminator)
2644 gfc_add_block_to_block (&body, &body1);
2646 else
2648 /* Increment count. */
2649 tmp1 = fold (build2 (PLUS_EXPR, gfc_array_index_type, count,
2650 gfc_index_one_node));
2651 gfc_add_modify_expr (&body1, count, tmp1);
2653 /* Generate the copying loops. */
2654 gfc_trans_scalarizing_loops (&loop, &body1);
2656 gfc_add_block_to_block (&body, &loop.pre);
2657 gfc_add_block_to_block (&body, &loop.post);
2659 gfc_cleanup_loop (&loop);
2660 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
2661 as tree nodes in SS may not be valid in different scope. */
2664 tmp1 = gfc_finish_block (&body);
2665 /* If the WHERE construct is inside FORALL, fill the full temporary. */
2666 if (nested_forall_info != NULL)
2667 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1, 1);
2670 gfc_add_expr_to_block (block, tmp1);
2672 *mask = tmp;
2673 *nmask = ntmp;
2675 return tmp1;
2679 /* Translate an assignment statement in a WHERE statement or construct
2680 statement. The MASK expression is used to control which elements
2681 of EXPR1 shall be assigned. */
2683 static tree
2684 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2, tree mask,
2685 tree count1, tree count2)
2687 gfc_se lse;
2688 gfc_se rse;
2689 gfc_ss *lss;
2690 gfc_ss *lss_section;
2691 gfc_ss *rss;
2693 gfc_loopinfo loop;
2694 tree tmp;
2695 stmtblock_t block;
2696 stmtblock_t body;
2697 tree index, maskexpr, tmp1;
2699 #if 0
2700 /* TODO: handle this special case.
2701 Special case a single function returning an array. */
2702 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
2704 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2705 if (tmp)
2706 return tmp;
2708 #endif
2710 /* Assignment of the form lhs = rhs. */
2711 gfc_start_block (&block);
2713 gfc_init_se (&lse, NULL);
2714 gfc_init_se (&rse, NULL);
2716 /* Walk the lhs. */
2717 lss = gfc_walk_expr (expr1);
2718 rss = NULL;
2720 /* In each where-assign-stmt, the mask-expr and the variable being
2721 defined shall be arrays of the same shape. */
2722 gcc_assert (lss != gfc_ss_terminator);
2724 /* The assignment needs scalarization. */
2725 lss_section = lss;
2727 /* Find a non-scalar SS from the lhs. */
2728 while (lss_section != gfc_ss_terminator
2729 && lss_section->type != GFC_SS_SECTION)
2730 lss_section = lss_section->next;
2732 gcc_assert (lss_section != gfc_ss_terminator);
2734 /* Initialize the scalarizer. */
2735 gfc_init_loopinfo (&loop);
2737 /* Walk the rhs. */
2738 rss = gfc_walk_expr (expr2);
2739 if (rss == gfc_ss_terminator)
2741 /* The rhs is scalar. Add a ss for the expression. */
2742 rss = gfc_get_ss ();
2743 rss->next = gfc_ss_terminator;
2744 rss->type = GFC_SS_SCALAR;
2745 rss->expr = expr2;
2748 /* Associate the SS with the loop. */
2749 gfc_add_ss_to_loop (&loop, lss);
2750 gfc_add_ss_to_loop (&loop, rss);
2752 /* Calculate the bounds of the scalarization. */
2753 gfc_conv_ss_startstride (&loop);
2755 /* Resolve any data dependencies in the statement. */
2756 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2758 /* Setup the scalarizing loops. */
2759 gfc_conv_loop_setup (&loop);
2761 /* Setup the gfc_se structures. */
2762 gfc_copy_loopinfo_to_se (&lse, &loop);
2763 gfc_copy_loopinfo_to_se (&rse, &loop);
2765 rse.ss = rss;
2766 gfc_mark_ss_chain_used (rss, 1);
2767 if (loop.temp_ss == NULL)
2769 lse.ss = lss;
2770 gfc_mark_ss_chain_used (lss, 1);
2772 else
2774 lse.ss = loop.temp_ss;
2775 gfc_mark_ss_chain_used (lss, 3);
2776 gfc_mark_ss_chain_used (loop.temp_ss, 3);
2779 /* Start the scalarized loop body. */
2780 gfc_start_scalarized_body (&loop, &body);
2782 /* Translate the expression. */
2783 gfc_conv_expr (&rse, expr2);
2784 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2786 gfc_conv_tmp_array_ref (&lse);
2787 gfc_advance_se_ss_chain (&lse);
2789 else
2790 gfc_conv_expr (&lse, expr1);
2792 /* Form the mask expression according to the mask tree list. */
2793 index = count1;
2794 tmp = mask;
2795 if (tmp != NULL)
2796 maskexpr = gfc_build_array_ref (tmp, index);
2797 else
2798 maskexpr = NULL;
2800 tmp = TREE_CHAIN (tmp);
2801 while (tmp)
2803 tmp1 = gfc_build_array_ref (tmp, index);
2804 maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1), maskexpr, tmp1);
2805 tmp = TREE_CHAIN (tmp);
2807 /* Use the scalar assignment as is. */
2808 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2809 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
2811 gfc_add_expr_to_block (&body, tmp);
2813 if (lss == gfc_ss_terminator)
2815 /* Increment count1. */
2816 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2817 count1, gfc_index_one_node));
2818 gfc_add_modify_expr (&body, count1, tmp);
2820 /* Use the scalar assignment as is. */
2821 gfc_add_block_to_block (&block, &body);
2823 else
2825 gcc_assert (lse.ss == gfc_ss_terminator
2826 && rse.ss == gfc_ss_terminator);
2828 if (loop.temp_ss != NULL)
2830 /* Increment count1 before finish the main body of a scalarized
2831 expression. */
2832 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2833 count1, gfc_index_one_node));
2834 gfc_add_modify_expr (&body, count1, tmp);
2835 gfc_trans_scalarized_loop_boundary (&loop, &body);
2837 /* We need to copy the temporary to the actual lhs. */
2838 gfc_init_se (&lse, NULL);
2839 gfc_init_se (&rse, NULL);
2840 gfc_copy_loopinfo_to_se (&lse, &loop);
2841 gfc_copy_loopinfo_to_se (&rse, &loop);
2843 rse.ss = loop.temp_ss;
2844 lse.ss = lss;
2846 gfc_conv_tmp_array_ref (&rse);
2847 gfc_advance_se_ss_chain (&rse);
2848 gfc_conv_expr (&lse, expr1);
2850 gcc_assert (lse.ss == gfc_ss_terminator
2851 && rse.ss == gfc_ss_terminator);
2853 /* Form the mask expression according to the mask tree list. */
2854 index = count2;
2855 tmp = mask;
2856 if (tmp != NULL)
2857 maskexpr = gfc_build_array_ref (tmp, index);
2858 else
2859 maskexpr = NULL;
2861 tmp = TREE_CHAIN (tmp);
2862 while (tmp)
2864 tmp1 = gfc_build_array_ref (tmp, index);
2865 maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
2866 maskexpr, tmp1);
2867 tmp = TREE_CHAIN (tmp);
2869 /* Use the scalar assignment as is. */
2870 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2871 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
2872 gfc_add_expr_to_block (&body, tmp);
2874 /* Increment count2. */
2875 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2876 count2, gfc_index_one_node));
2877 gfc_add_modify_expr (&body, count2, tmp);
2879 else
2881 /* Increment count1. */
2882 tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2883 count1, gfc_index_one_node));
2884 gfc_add_modify_expr (&body, count1, tmp);
2887 /* Generate the copying loops. */
2888 gfc_trans_scalarizing_loops (&loop, &body);
2890 /* Wrap the whole thing up. */
2891 gfc_add_block_to_block (&block, &loop.pre);
2892 gfc_add_block_to_block (&block, &loop.post);
2893 gfc_cleanup_loop (&loop);
2896 return gfc_finish_block (&block);
2900 /* Translate the WHERE construct or statement.
2901 This fuction can be called iteratively to translate the nested WHERE
2902 construct or statement.
2903 MASK is the control mask, and PMASK is the pending control mask.
2904 TEMP records the temporary address which must be freed later. */
2906 static void
2907 gfc_trans_where_2 (gfc_code * code, tree mask, tree pmask,
2908 forall_info * nested_forall_info, stmtblock_t * block,
2909 temporary_list ** temp)
2911 gfc_expr *expr1;
2912 gfc_expr *expr2;
2913 gfc_code *cblock;
2914 gfc_code *cnext;
2915 tree tmp, tmp1, tmp2;
2916 tree count1, count2;
2917 tree mask_copy;
2918 int need_temp;
2920 /* the WHERE statement or the WHERE construct statement. */
2921 cblock = code->block;
2922 while (cblock)
2924 /* Has mask-expr. */
2925 if (cblock->expr)
2927 /* Ensure that the WHERE mask be evaluated only once. */
2928 tmp2 = gfc_evaluate_where_mask (cblock->expr, nested_forall_info,
2929 &tmp, &tmp1, temp, block);
2931 /* Set the control mask and the pending control mask. */
2932 /* It's a where-stmt. */
2933 if (mask == NULL)
2935 mask = tmp;
2936 pmask = tmp1;
2938 /* It's a nested where-stmt. */
2939 else if (mask && pmask == NULL)
2941 tree tmp2;
2942 /* Use the TREE_CHAIN to list the masks. */
2943 tmp2 = copy_list (mask);
2944 pmask = chainon (mask, tmp1);
2945 mask = chainon (tmp2, tmp);
2947 /* It's a masked-elsewhere-stmt. */
2948 else if (mask && cblock->expr)
2950 tree tmp2;
2951 tmp2 = copy_list (pmask);
2953 mask = pmask;
2954 tmp2 = chainon (tmp2, tmp);
2955 pmask = chainon (mask, tmp1);
2956 mask = tmp2;
2959 /* It's a elsewhere-stmt. No mask-expr is present. */
2960 else
2961 mask = pmask;
2963 /* Get the assignment statement of a WHERE statement, or the first
2964 statement in where-body-construct of a WHERE construct. */
2965 cnext = cblock->next;
2966 while (cnext)
2968 switch (cnext->op)
2970 /* WHERE assignment statement. */
2971 case EXEC_ASSIGN:
2972 expr1 = cnext->expr;
2973 expr2 = cnext->expr2;
2974 if (nested_forall_info != NULL)
2976 int nvar;
2977 gfc_expr **varexpr;
2979 nvar = nested_forall_info->nvar;
2980 varexpr = (gfc_expr **)
2981 gfc_getmem (nvar * sizeof (gfc_expr *));
2982 need_temp = gfc_check_dependency (expr1, expr2, varexpr,
2983 nvar);
2984 if (need_temp)
2985 gfc_trans_assign_need_temp (expr1, expr2, mask,
2986 nested_forall_info, block);
2987 else
2989 /* Variables to control maskexpr. */
2990 count1 = gfc_create_var (gfc_array_index_type, "count1");
2991 count2 = gfc_create_var (gfc_array_index_type, "count2");
2992 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
2993 gfc_add_modify_expr (block, count2, gfc_index_zero_node);
2995 tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
2996 count2);
2997 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
2998 tmp, 1, 1);
2999 gfc_add_expr_to_block (block, tmp);
3002 else
3004 /* Variables to control maskexpr. */
3005 count1 = gfc_create_var (gfc_array_index_type, "count1");
3006 count2 = gfc_create_var (gfc_array_index_type, "count2");
3007 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
3008 gfc_add_modify_expr (block, count2, gfc_index_zero_node);
3010 tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3011 count2);
3012 gfc_add_expr_to_block (block, tmp);
3015 break;
3017 /* WHERE or WHERE construct is part of a where-body-construct. */
3018 case EXEC_WHERE:
3019 /* Ensure that MASK is not modified by next gfc_trans_where_2. */
3020 mask_copy = copy_list (mask);
3021 gfc_trans_where_2 (cnext, mask_copy, NULL, nested_forall_info,
3022 block, temp);
3023 break;
3025 default:
3026 gcc_unreachable ();
3029 /* The next statement within the same where-body-construct. */
3030 cnext = cnext->next;
3032 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
3033 cblock = cblock->block;
3038 /* As the WHERE or WHERE construct statement can be nested, we call
3039 gfc_trans_where_2 to do the translation, and pass the initial
3040 NULL values for both the control mask and the pending control mask. */
3042 tree
3043 gfc_trans_where (gfc_code * code)
3045 stmtblock_t block;
3046 temporary_list *temp, *p;
3047 tree args;
3048 tree tmp;
3050 gfc_start_block (&block);
3051 temp = NULL;
3053 gfc_trans_where_2 (code, NULL, NULL, NULL, &block, &temp);
3055 /* Add calls to free temporaries which were dynamically allocated. */
3056 while (temp)
3058 args = gfc_chainon_list (NULL_TREE, temp->temporary);
3059 tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
3060 gfc_add_expr_to_block (&block, tmp);
3062 p = temp;
3063 temp = temp->next;
3064 gfc_free (p);
3066 return gfc_finish_block (&block);
3070 /* CYCLE a DO loop. The label decl has already been created by
3071 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
3072 node at the head of the loop. We must mark the label as used. */
3074 tree
3075 gfc_trans_cycle (gfc_code * code)
3077 tree cycle_label;
3079 cycle_label = TREE_PURPOSE (code->ext.whichloop->backend_decl);
3080 TREE_USED (cycle_label) = 1;
3081 return build1_v (GOTO_EXPR, cycle_label);
3085 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
3086 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
3087 loop. */
3089 tree
3090 gfc_trans_exit (gfc_code * code)
3092 tree exit_label;
3094 exit_label = TREE_VALUE (code->ext.whichloop->backend_decl);
3095 TREE_USED (exit_label) = 1;
3096 return build1_v (GOTO_EXPR, exit_label);
3100 /* Translate the ALLOCATE statement. */
3102 tree
3103 gfc_trans_allocate (gfc_code * code)
3105 gfc_alloc *al;
3106 gfc_expr *expr;
3107 gfc_se se;
3108 tree tmp;
3109 tree parm;
3110 gfc_ref *ref;
3111 tree stat;
3112 tree pstat;
3113 tree error_label;
3114 stmtblock_t block;
3116 if (!code->ext.alloc_list)
3117 return NULL_TREE;
3119 gfc_start_block (&block);
3121 if (code->expr)
3123 tree gfc_int4_type_node = gfc_get_int_type (4);
3125 stat = gfc_create_var (gfc_int4_type_node, "stat");
3126 pstat = gfc_build_addr_expr (NULL, stat);
3128 error_label = gfc_build_label_decl (NULL_TREE);
3129 TREE_USED (error_label) = 1;
3131 else
3133 pstat = integer_zero_node;
3134 stat = error_label = NULL_TREE;
3138 for (al = code->ext.alloc_list; al != NULL; al = al->next)
3140 expr = al->expr;
3142 gfc_init_se (&se, NULL);
3143 gfc_start_block (&se.pre);
3145 se.want_pointer = 1;
3146 se.descriptor_only = 1;
3147 gfc_conv_expr (&se, expr);
3149 ref = expr->ref;
3151 /* Find the last reference in the chain. */
3152 while (ref && ref->next != NULL)
3154 gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3155 ref = ref->next;
3158 if (ref != NULL && ref->type == REF_ARRAY)
3160 /* An array. */
3161 gfc_array_allocate (&se, ref, pstat);
3163 else
3165 /* A scalar or derived type. */
3166 tree val;
3168 val = gfc_create_var (ppvoid_type_node, "ptr");
3169 tmp = gfc_build_addr_expr (ppvoid_type_node, se.expr);
3170 gfc_add_modify_expr (&se.pre, val, tmp);
3172 tmp = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
3173 parm = gfc_chainon_list (NULL_TREE, val);
3174 parm = gfc_chainon_list (parm, tmp);
3175 parm = gfc_chainon_list (parm, pstat);
3176 tmp = gfc_build_function_call (gfor_fndecl_allocate, parm);
3177 gfc_add_expr_to_block (&se.pre, tmp);
3179 if (code->expr)
3181 tmp = build1_v (GOTO_EXPR, error_label);
3182 parm =
3183 build2 (NE_EXPR, boolean_type_node, stat, integer_zero_node);
3184 tmp = build3_v (COND_EXPR, parm, tmp, build_empty_stmt ());
3185 gfc_add_expr_to_block (&se.pre, tmp);
3189 tmp = gfc_finish_block (&se.pre);
3190 gfc_add_expr_to_block (&block, tmp);
3193 /* Assign the value to the status variable. */
3194 if (code->expr)
3196 tmp = build1_v (LABEL_EXPR, error_label);
3197 gfc_add_expr_to_block (&block, tmp);
3199 gfc_init_se (&se, NULL);
3200 gfc_conv_expr_lhs (&se, code->expr);
3201 tmp = convert (TREE_TYPE (se.expr), stat);
3202 gfc_add_modify_expr (&block, se.expr, tmp);
3205 return gfc_finish_block (&block);
3209 tree
3210 gfc_trans_deallocate (gfc_code * code)
3212 gfc_se se;
3213 gfc_alloc *al;
3214 gfc_expr *expr;
3215 tree var;
3216 tree tmp;
3217 tree type;
3218 stmtblock_t block;
3220 gfc_start_block (&block);
3222 for (al = code->ext.alloc_list; al != NULL; al = al->next)
3224 expr = al->expr;
3225 gcc_assert (expr->expr_type == EXPR_VARIABLE);
3227 gfc_init_se (&se, NULL);
3228 gfc_start_block (&se.pre);
3230 se.want_pointer = 1;
3231 se.descriptor_only = 1;
3232 gfc_conv_expr (&se, expr);
3234 if (expr->symtree->n.sym->attr.dimension)
3236 tmp = gfc_array_deallocate (se.expr);
3237 gfc_add_expr_to_block (&se.pre, tmp);
3239 else
3241 type = build_pointer_type (TREE_TYPE (se.expr));
3242 var = gfc_create_var (type, "ptr");
3243 tmp = gfc_build_addr_expr (type, se.expr);
3244 gfc_add_modify_expr (&se.pre, var, tmp);
3246 tmp = gfc_chainon_list (NULL_TREE, var);
3247 tmp = gfc_chainon_list (tmp, integer_zero_node);
3248 tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
3249 gfc_add_expr_to_block (&se.pre, tmp);
3251 tmp = gfc_finish_block (&se.pre);
3252 gfc_add_expr_to_block (&block, tmp);
3255 return gfc_finish_block (&block);