gcc:
[official-gcc.git] / gcc / fortran / trans-stmt.c
blobf0fefdc3580f4b0847460badb5b7d24baf186470
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, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, 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 typedef struct iter_info
42 tree var;
43 tree start;
44 tree end;
45 tree step;
46 struct iter_info *next;
48 iter_info;
50 typedef struct temporary_list
52 tree temporary;
53 struct temporary_list *next;
55 temporary_list;
57 typedef struct forall_info
59 iter_info *this_loop;
60 tree mask;
61 tree pmask;
62 tree maskindex;
63 int nvar;
64 tree size;
65 struct forall_info *outer;
66 struct forall_info *next_nest;
68 forall_info;
70 static void gfc_trans_where_2 (gfc_code *, tree, tree, forall_info *,
71 stmtblock_t *, temporary_list **temp);
73 /* Translate a F95 label number to a LABEL_EXPR. */
75 tree
76 gfc_trans_label_here (gfc_code * code)
78 return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
82 /* Given a variable expression which has been ASSIGNed to, find the decl
83 containing the auxiliary variables. For variables in common blocks this
84 is a field_decl. */
86 void
87 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
89 gcc_assert (expr->symtree->n.sym->attr.assign == 1);
90 gfc_conv_expr (se, expr);
91 /* Deals with variable in common block. Get the field declaration. */
92 if (TREE_CODE (se->expr) == COMPONENT_REF)
93 se->expr = TREE_OPERAND (se->expr, 1);
94 /* Deals with dummy argument. Get the parameter declaration. */
95 else if (TREE_CODE (se->expr) == INDIRECT_REF)
96 se->expr = TREE_OPERAND (se->expr, 0);
99 /* Translate a label assignment statement. */
101 tree
102 gfc_trans_label_assign (gfc_code * code)
104 tree label_tree;
105 gfc_se se;
106 tree len;
107 tree addr;
108 tree len_tree;
109 char *label_str;
110 int label_len;
112 /* Start a new block. */
113 gfc_init_se (&se, NULL);
114 gfc_start_block (&se.pre);
115 gfc_conv_label_variable (&se, code->expr);
117 len = GFC_DECL_STRING_LEN (se.expr);
118 addr = GFC_DECL_ASSIGN_ADDR (se.expr);
120 label_tree = gfc_get_label_decl (code->label);
122 if (code->label->defined == ST_LABEL_TARGET)
124 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
125 len_tree = integer_minus_one_node;
127 else
129 label_str = code->label->format->value.character.string;
130 label_len = code->label->format->value.character.length;
131 len_tree = build_int_cst (NULL_TREE, label_len);
132 label_tree = gfc_build_string_const (label_len + 1, label_str);
133 label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
136 gfc_add_modify_expr (&se.pre, len, len_tree);
137 gfc_add_modify_expr (&se.pre, addr, label_tree);
139 return gfc_finish_block (&se.pre);
142 /* Translate a GOTO statement. */
144 tree
145 gfc_trans_goto (gfc_code * code)
147 tree assigned_goto;
148 tree target;
149 tree tmp;
150 tree assign_error;
151 tree range_error;
152 gfc_se se;
155 if (code->label != NULL)
156 return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
158 /* ASSIGNED GOTO. */
159 gfc_init_se (&se, NULL);
160 gfc_start_block (&se.pre);
161 gfc_conv_label_variable (&se, code->expr);
162 assign_error =
163 gfc_build_cstring_const ("Assigned label is not a target label");
164 tmp = GFC_DECL_STRING_LEN (se.expr);
165 tmp = build2 (NE_EXPR, boolean_type_node, tmp, integer_minus_one_node);
166 gfc_trans_runtime_check (tmp, assign_error, &se.pre);
168 assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
170 code = code->block;
171 if (code == NULL)
173 target = build1 (GOTO_EXPR, void_type_node, assigned_goto);
174 gfc_add_expr_to_block (&se.pre, target);
175 return gfc_finish_block (&se.pre);
178 /* Check the label list. */
179 range_error = gfc_build_cstring_const ("Assigned label is not in the list");
183 target = gfc_get_label_decl (code->label);
184 tmp = gfc_build_addr_expr (pvoid_type_node, target);
185 tmp = build2 (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
186 tmp = build3_v (COND_EXPR, tmp,
187 build1 (GOTO_EXPR, void_type_node, target),
188 build_empty_stmt ());
189 gfc_add_expr_to_block (&se.pre, tmp);
190 code = code->block;
192 while (code != NULL);
193 gfc_trans_runtime_check (boolean_true_node, range_error, &se.pre);
194 return gfc_finish_block (&se.pre);
198 /* Translate an ENTRY statement. Just adds a label for this entry point. */
199 tree
200 gfc_trans_entry (gfc_code * code)
202 return build1_v (LABEL_EXPR, code->ext.entry->label);
206 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
208 tree
209 gfc_trans_call (gfc_code * code)
211 gfc_se se;
212 int has_alternate_specifier;
214 /* A CALL starts a new block because the actual arguments may have to
215 be evaluated first. */
216 gfc_init_se (&se, NULL);
217 gfc_start_block (&se.pre);
219 gcc_assert (code->resolved_sym);
221 /* Translate the call. */
222 has_alternate_specifier
223 = gfc_conv_function_call (&se, code->resolved_sym, code->ext.actual);
225 /* A subroutine without side-effect, by definition, does nothing! */
226 TREE_SIDE_EFFECTS (se.expr) = 1;
228 /* Chain the pieces together and return the block. */
229 if (has_alternate_specifier)
231 gfc_code *select_code;
232 gfc_symbol *sym;
233 select_code = code->next;
234 gcc_assert(select_code->op == EXEC_SELECT);
235 sym = select_code->expr->symtree->n.sym;
236 se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
237 gfc_add_modify_expr (&se.pre, sym->backend_decl, se.expr);
239 else
240 gfc_add_expr_to_block (&se.pre, se.expr);
242 gfc_add_block_to_block (&se.pre, &se.post);
243 return gfc_finish_block (&se.pre);
247 /* Translate the RETURN statement. */
249 tree
250 gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
252 if (code->expr)
254 gfc_se se;
255 tree tmp;
256 tree result;
258 /* if code->expr is not NULL, this return statement must appear
259 in a subroutine and current_fake_result_decl has already
260 been generated. */
262 result = gfc_get_fake_result_decl (NULL);
263 if (!result)
265 gfc_warning ("An alternate return at %L without a * dummy argument",
266 &code->expr->where);
267 return build1_v (GOTO_EXPR, gfc_get_return_label ());
270 /* Start a new block for this statement. */
271 gfc_init_se (&se, NULL);
272 gfc_start_block (&se.pre);
274 gfc_conv_expr (&se, code->expr);
276 tmp = build2 (MODIFY_EXPR, TREE_TYPE (result), result, se.expr);
277 gfc_add_expr_to_block (&se.pre, tmp);
279 tmp = build1_v (GOTO_EXPR, gfc_get_return_label ());
280 gfc_add_expr_to_block (&se.pre, tmp);
281 gfc_add_block_to_block (&se.pre, &se.post);
282 return gfc_finish_block (&se.pre);
284 else
285 return build1_v (GOTO_EXPR, gfc_get_return_label ());
289 /* Translate the PAUSE statement. We have to translate this statement
290 to a runtime library call. */
292 tree
293 gfc_trans_pause (gfc_code * code)
295 tree gfc_int4_type_node = gfc_get_int_type (4);
296 gfc_se se;
297 tree args;
298 tree tmp;
299 tree fndecl;
301 /* Start a new block for this statement. */
302 gfc_init_se (&se, NULL);
303 gfc_start_block (&se.pre);
306 if (code->expr == NULL)
308 tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
309 args = gfc_chainon_list (NULL_TREE, tmp);
310 fndecl = gfor_fndecl_pause_numeric;
312 else
314 gfc_conv_expr_reference (&se, code->expr);
315 args = gfc_chainon_list (NULL_TREE, se.expr);
316 args = gfc_chainon_list (args, se.string_length);
317 fndecl = gfor_fndecl_pause_string;
320 tmp = gfc_build_function_call (fndecl, args);
321 gfc_add_expr_to_block (&se.pre, tmp);
323 gfc_add_block_to_block (&se.pre, &se.post);
325 return gfc_finish_block (&se.pre);
329 /* Translate the STOP statement. We have to translate this statement
330 to a runtime library call. */
332 tree
333 gfc_trans_stop (gfc_code * code)
335 tree gfc_int4_type_node = gfc_get_int_type (4);
336 gfc_se se;
337 tree args;
338 tree tmp;
339 tree fndecl;
341 /* Start a new block for this statement. */
342 gfc_init_se (&se, NULL);
343 gfc_start_block (&se.pre);
346 if (code->expr == NULL)
348 tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
349 args = gfc_chainon_list (NULL_TREE, tmp);
350 fndecl = gfor_fndecl_stop_numeric;
352 else
354 gfc_conv_expr_reference (&se, code->expr);
355 args = gfc_chainon_list (NULL_TREE, se.expr);
356 args = gfc_chainon_list (args, se.string_length);
357 fndecl = gfor_fndecl_stop_string;
360 tmp = gfc_build_function_call (fndecl, args);
361 gfc_add_expr_to_block (&se.pre, tmp);
363 gfc_add_block_to_block (&se.pre, &se.post);
365 return gfc_finish_block (&se.pre);
369 /* Generate GENERIC for the IF construct. This function also deals with
370 the simple IF statement, because the front end translates the IF
371 statement into an IF construct.
373 We translate:
375 IF (cond) THEN
376 then_clause
377 ELSEIF (cond2)
378 elseif_clause
379 ELSE
380 else_clause
381 ENDIF
383 into:
385 pre_cond_s;
386 if (cond_s)
388 then_clause;
390 else
392 pre_cond_s
393 if (cond_s)
395 elseif_clause
397 else
399 else_clause;
403 where COND_S is the simplified version of the predicate. PRE_COND_S
404 are the pre side-effects produced by the translation of the
405 conditional.
406 We need to build the chain recursively otherwise we run into
407 problems with folding incomplete statements. */
409 static tree
410 gfc_trans_if_1 (gfc_code * code)
412 gfc_se if_se;
413 tree stmt, elsestmt;
415 /* Check for an unconditional ELSE clause. */
416 if (!code->expr)
417 return gfc_trans_code (code->next);
419 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
420 gfc_init_se (&if_se, NULL);
421 gfc_start_block (&if_se.pre);
423 /* Calculate the IF condition expression. */
424 gfc_conv_expr_val (&if_se, code->expr);
426 /* Translate the THEN clause. */
427 stmt = gfc_trans_code (code->next);
429 /* Translate the ELSE clause. */
430 if (code->block)
431 elsestmt = gfc_trans_if_1 (code->block);
432 else
433 elsestmt = build_empty_stmt ();
435 /* Build the condition expression and add it to the condition block. */
436 stmt = build3_v (COND_EXPR, if_se.expr, stmt, elsestmt);
438 gfc_add_expr_to_block (&if_se.pre, stmt);
440 /* Finish off this statement. */
441 return gfc_finish_block (&if_se.pre);
444 tree
445 gfc_trans_if (gfc_code * code)
447 /* Ignore the top EXEC_IF, it only announces an IF construct. The
448 actual code we must translate is in code->block. */
450 return gfc_trans_if_1 (code->block);
454 /* Translage an arithmetic IF expression.
456 IF (cond) label1, label2, label3 translates to
458 if (cond <= 0)
460 if (cond < 0)
461 goto label1;
462 else // cond == 0
463 goto label2;
465 else // cond > 0
466 goto label3;
468 An optimized version can be generated in case of equal labels.
469 E.g., if label1 is equal to label2, we can translate it to
471 if (cond <= 0)
472 goto label1;
473 else
474 goto label3;
477 tree
478 gfc_trans_arithmetic_if (gfc_code * code)
480 gfc_se se;
481 tree tmp;
482 tree branch1;
483 tree branch2;
484 tree zero;
486 /* Start a new block. */
487 gfc_init_se (&se, NULL);
488 gfc_start_block (&se.pre);
490 /* Pre-evaluate COND. */
491 gfc_conv_expr_val (&se, code->expr);
493 /* Build something to compare with. */
494 zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
496 if (code->label->value != code->label2->value)
498 /* If (cond < 0) take branch1 else take branch2.
499 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
500 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
501 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
503 if (code->label->value != code->label3->value)
504 tmp = build2 (LT_EXPR, boolean_type_node, se.expr, zero);
505 else
506 tmp = build2 (NE_EXPR, boolean_type_node, se.expr, zero);
508 branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
510 else
511 branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
513 if (code->label->value != code->label3->value
514 && code->label2->value != code->label3->value)
516 /* if (cond <= 0) take branch1 else take branch2. */
517 branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
518 tmp = build2 (LE_EXPR, boolean_type_node, se.expr, zero);
519 branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
522 /* Append the COND_EXPR to the evaluation of COND, and return. */
523 gfc_add_expr_to_block (&se.pre, branch1);
524 return gfc_finish_block (&se.pre);
528 /* Translate the simple DO construct. This is where the loop variable has
529 integer type and step +-1. We can't use this in the general case
530 because integer overflow and floating point errors could give incorrect
531 results.
532 We translate a do loop from:
534 DO dovar = from, to, step
535 body
536 END DO
540 [Evaluate loop bounds and step]
541 dovar = from;
542 if ((step > 0) ? (dovar <= to) : (dovar => to))
544 for (;;)
546 body;
547 cycle_label:
548 cond = (dovar == to);
549 dovar += step;
550 if (cond) goto end_label;
553 end_label:
555 This helps the optimizers by avoiding the extra induction variable
556 used in the general case. */
558 static tree
559 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
560 tree from, tree to, tree step)
562 stmtblock_t body;
563 tree type;
564 tree cond;
565 tree tmp;
566 tree cycle_label;
567 tree exit_label;
569 type = TREE_TYPE (dovar);
571 /* Initialize the DO variable: dovar = from. */
572 gfc_add_modify_expr (pblock, dovar, from);
574 /* Cycle and exit statements are implemented with gotos. */
575 cycle_label = gfc_build_label_decl (NULL_TREE);
576 exit_label = gfc_build_label_decl (NULL_TREE);
578 /* Put the labels where they can be found later. See gfc_trans_do(). */
579 code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
581 /* Loop body. */
582 gfc_start_block (&body);
584 /* Main loop body. */
585 tmp = gfc_trans_code (code->block->next);
586 gfc_add_expr_to_block (&body, tmp);
588 /* Label for cycle statements (if needed). */
589 if (TREE_USED (cycle_label))
591 tmp = build1_v (LABEL_EXPR, cycle_label);
592 gfc_add_expr_to_block (&body, tmp);
595 /* Evaluate the loop condition. */
596 cond = build2 (EQ_EXPR, boolean_type_node, dovar, to);
597 cond = gfc_evaluate_now (cond, &body);
599 /* Increment the loop variable. */
600 tmp = build2 (PLUS_EXPR, type, dovar, step);
601 gfc_add_modify_expr (&body, dovar, tmp);
603 /* The loop exit. */
604 tmp = build1_v (GOTO_EXPR, exit_label);
605 TREE_USED (exit_label) = 1;
606 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
607 gfc_add_expr_to_block (&body, tmp);
609 /* Finish the loop body. */
610 tmp = gfc_finish_block (&body);
611 tmp = build1_v (LOOP_EXPR, tmp);
613 /* Only execute the loop if the number of iterations is positive. */
614 if (tree_int_cst_sgn (step) > 0)
615 cond = fold_build2 (LE_EXPR, boolean_type_node, dovar, to);
616 else
617 cond = fold_build2 (GE_EXPR, boolean_type_node, dovar, to);
618 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
619 gfc_add_expr_to_block (pblock, tmp);
621 /* Add the exit label. */
622 tmp = build1_v (LABEL_EXPR, exit_label);
623 gfc_add_expr_to_block (pblock, tmp);
625 return gfc_finish_block (pblock);
628 /* Translate the DO construct. This obviously is one of the most
629 important ones to get right with any compiler, but especially
630 so for Fortran.
632 We special case some loop forms as described in gfc_trans_simple_do.
633 For other cases we implement them with a separate loop count,
634 as described in the standard.
636 We translate a do loop from:
638 DO dovar = from, to, step
639 body
640 END DO
644 [evaluate loop bounds and step]
645 count = to + step - from;
646 dovar = from;
647 for (;;)
649 body;
650 cycle_label:
651 dovar += step
652 count--;
653 if (count <=0) goto exit_label;
655 exit_label:
657 TODO: Large loop counts
658 The code above assumes the loop count fits into a signed integer kind,
659 i.e. Does not work for loop counts > 2^31 for integer(kind=4) variables
660 We must support the full range. */
662 tree
663 gfc_trans_do (gfc_code * code)
665 gfc_se se;
666 tree dovar;
667 tree from;
668 tree to;
669 tree step;
670 tree count;
671 tree count_one;
672 tree type;
673 tree cond;
674 tree cycle_label;
675 tree exit_label;
676 tree tmp;
677 stmtblock_t block;
678 stmtblock_t body;
680 gfc_start_block (&block);
682 /* Evaluate all the expressions in the iterator. */
683 gfc_init_se (&se, NULL);
684 gfc_conv_expr_lhs (&se, code->ext.iterator->var);
685 gfc_add_block_to_block (&block, &se.pre);
686 dovar = se.expr;
687 type = TREE_TYPE (dovar);
689 gfc_init_se (&se, NULL);
690 gfc_conv_expr_val (&se, code->ext.iterator->start);
691 gfc_add_block_to_block (&block, &se.pre);
692 from = gfc_evaluate_now (se.expr, &block);
694 gfc_init_se (&se, NULL);
695 gfc_conv_expr_val (&se, code->ext.iterator->end);
696 gfc_add_block_to_block (&block, &se.pre);
697 to = gfc_evaluate_now (se.expr, &block);
699 gfc_init_se (&se, NULL);
700 gfc_conv_expr_val (&se, code->ext.iterator->step);
701 gfc_add_block_to_block (&block, &se.pre);
702 step = gfc_evaluate_now (se.expr, &block);
704 /* Special case simple loops. */
705 if (TREE_CODE (type) == INTEGER_TYPE
706 && (integer_onep (step)
707 || tree_int_cst_equal (step, integer_minus_one_node)))
708 return gfc_trans_simple_do (code, &block, dovar, from, to, step);
710 /* Initialize loop count. This code is executed before we enter the
711 loop body. We generate: count = (to + step - from) / step. */
713 tmp = fold_build2 (MINUS_EXPR, type, step, from);
714 tmp = fold_build2 (PLUS_EXPR, type, to, tmp);
715 if (TREE_CODE (type) == INTEGER_TYPE)
717 tmp = fold_build2 (TRUNC_DIV_EXPR, type, tmp, step);
718 count = gfc_create_var (type, "count");
720 else
722 /* TODO: We could use the same width as the real type.
723 This would probably cause more problems that it solves
724 when we implement "long double" types. */
725 tmp = fold_build2 (RDIV_EXPR, type, tmp, step);
726 tmp = fold_build1 (FIX_TRUNC_EXPR, gfc_array_index_type, tmp);
727 count = gfc_create_var (gfc_array_index_type, "count");
729 gfc_add_modify_expr (&block, count, tmp);
731 count_one = convert (TREE_TYPE (count), integer_one_node);
733 /* Initialize the DO variable: dovar = from. */
734 gfc_add_modify_expr (&block, dovar, from);
736 /* Loop body. */
737 gfc_start_block (&body);
739 /* Cycle and exit statements are implemented with gotos. */
740 cycle_label = gfc_build_label_decl (NULL_TREE);
741 exit_label = gfc_build_label_decl (NULL_TREE);
743 /* Start with the loop condition. Loop until count <= 0. */
744 cond = build2 (LE_EXPR, boolean_type_node, count,
745 convert (TREE_TYPE (count), integer_zero_node));
746 tmp = build1_v (GOTO_EXPR, exit_label);
747 TREE_USED (exit_label) = 1;
748 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
749 gfc_add_expr_to_block (&body, tmp);
751 /* Put these labels where they can be found later. We put the
752 labels in a TREE_LIST node (because TREE_CHAIN is already
753 used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
754 label in TREE_VALUE (backend_decl). */
756 code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
758 /* Main loop body. */
759 tmp = gfc_trans_code (code->block->next);
760 gfc_add_expr_to_block (&body, tmp);
762 /* Label for cycle statements (if needed). */
763 if (TREE_USED (cycle_label))
765 tmp = build1_v (LABEL_EXPR, cycle_label);
766 gfc_add_expr_to_block (&body, tmp);
769 /* Increment the loop variable. */
770 tmp = build2 (PLUS_EXPR, type, dovar, step);
771 gfc_add_modify_expr (&body, dovar, tmp);
773 /* Decrement the loop count. */
774 tmp = build2 (MINUS_EXPR, TREE_TYPE (count), count, count_one);
775 gfc_add_modify_expr (&body, count, tmp);
777 /* End of loop body. */
778 tmp = gfc_finish_block (&body);
780 /* The for loop itself. */
781 tmp = build1_v (LOOP_EXPR, tmp);
782 gfc_add_expr_to_block (&block, tmp);
784 /* Add the exit label. */
785 tmp = build1_v (LABEL_EXPR, exit_label);
786 gfc_add_expr_to_block (&block, tmp);
788 return gfc_finish_block (&block);
792 /* Translate the DO WHILE construct.
794 We translate
796 DO WHILE (cond)
797 body
798 END DO
802 for ( ; ; )
804 pre_cond;
805 if (! cond) goto exit_label;
806 body;
807 cycle_label:
809 exit_label:
811 Because the evaluation of the exit condition `cond' may have side
812 effects, we can't do much for empty loop bodies. The backend optimizers
813 should be smart enough to eliminate any dead loops. */
815 tree
816 gfc_trans_do_while (gfc_code * code)
818 gfc_se cond;
819 tree tmp;
820 tree cycle_label;
821 tree exit_label;
822 stmtblock_t block;
824 /* Everything we build here is part of the loop body. */
825 gfc_start_block (&block);
827 /* Cycle and exit statements are implemented with gotos. */
828 cycle_label = gfc_build_label_decl (NULL_TREE);
829 exit_label = gfc_build_label_decl (NULL_TREE);
831 /* Put the labels where they can be found later. See gfc_trans_do(). */
832 code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
834 /* Create a GIMPLE version of the exit condition. */
835 gfc_init_se (&cond, NULL);
836 gfc_conv_expr_val (&cond, code->expr);
837 gfc_add_block_to_block (&block, &cond.pre);
838 cond.expr = fold_build1 (TRUTH_NOT_EXPR, boolean_type_node, cond.expr);
840 /* Build "IF (! cond) GOTO exit_label". */
841 tmp = build1_v (GOTO_EXPR, exit_label);
842 TREE_USED (exit_label) = 1;
843 tmp = build3_v (COND_EXPR, cond.expr, tmp, build_empty_stmt ());
844 gfc_add_expr_to_block (&block, tmp);
846 /* The main body of the loop. */
847 tmp = gfc_trans_code (code->block->next);
848 gfc_add_expr_to_block (&block, tmp);
850 /* Label for cycle statements (if needed). */
851 if (TREE_USED (cycle_label))
853 tmp = build1_v (LABEL_EXPR, cycle_label);
854 gfc_add_expr_to_block (&block, tmp);
857 /* End of loop body. */
858 tmp = gfc_finish_block (&block);
860 gfc_init_block (&block);
861 /* Build the loop. */
862 tmp = build1_v (LOOP_EXPR, tmp);
863 gfc_add_expr_to_block (&block, tmp);
865 /* Add the exit label. */
866 tmp = build1_v (LABEL_EXPR, exit_label);
867 gfc_add_expr_to_block (&block, tmp);
869 return gfc_finish_block (&block);
873 /* Translate the SELECT CASE construct for INTEGER case expressions,
874 without killing all potential optimizations. The problem is that
875 Fortran allows unbounded cases, but the back-end does not, so we
876 need to intercept those before we enter the equivalent SWITCH_EXPR
877 we can build.
879 For example, we translate this,
881 SELECT CASE (expr)
882 CASE (:100,101,105:115)
883 block_1
884 CASE (190:199,200:)
885 block_2
886 CASE (300)
887 block_3
888 CASE DEFAULT
889 block_4
890 END SELECT
892 to the GENERIC equivalent,
894 switch (expr)
896 case (minimum value for typeof(expr) ... 100:
897 case 101:
898 case 105 ... 114:
899 block1:
900 goto end_label;
902 case 200 ... (maximum value for typeof(expr):
903 case 190 ... 199:
904 block2;
905 goto end_label;
907 case 300:
908 block_3;
909 goto end_label;
911 default:
912 block_4;
913 goto end_label;
916 end_label: */
918 static tree
919 gfc_trans_integer_select (gfc_code * code)
921 gfc_code *c;
922 gfc_case *cp;
923 tree end_label;
924 tree tmp;
925 gfc_se se;
926 stmtblock_t block;
927 stmtblock_t body;
929 gfc_start_block (&block);
931 /* Calculate the switch expression. */
932 gfc_init_se (&se, NULL);
933 gfc_conv_expr_val (&se, code->expr);
934 gfc_add_block_to_block (&block, &se.pre);
936 end_label = gfc_build_label_decl (NULL_TREE);
938 gfc_init_block (&body);
940 for (c = code->block; c; c = c->block)
942 for (cp = c->ext.case_list; cp; cp = cp->next)
944 tree low, high;
945 tree label;
947 /* Assume it's the default case. */
948 low = high = NULL_TREE;
950 if (cp->low)
952 low = gfc_conv_constant_to_tree (cp->low);
954 /* If there's only a lower bound, set the high bound to the
955 maximum value of the case expression. */
956 if (!cp->high)
957 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
960 if (cp->high)
962 /* Three cases are possible here:
964 1) There is no lower bound, e.g. CASE (:N).
965 2) There is a lower bound .NE. high bound, that is
966 a case range, e.g. CASE (N:M) where M>N (we make
967 sure that M>N during type resolution).
968 3) There is a lower bound, and it has the same value
969 as the high bound, e.g. CASE (N:N). This is our
970 internal representation of CASE(N).
972 In the first and second case, we need to set a value for
973 high. In the thirth case, we don't because the GCC middle
974 end represents a single case value by just letting high be
975 a NULL_TREE. We can't do that because we need to be able
976 to represent unbounded cases. */
978 if (!cp->low
979 || (cp->low
980 && mpz_cmp (cp->low->value.integer,
981 cp->high->value.integer) != 0))
982 high = gfc_conv_constant_to_tree (cp->high);
984 /* Unbounded case. */
985 if (!cp->low)
986 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
989 /* Build a label. */
990 label = gfc_build_label_decl (NULL_TREE);
992 /* Add this case label.
993 Add parameter 'label', make it match GCC backend. */
994 tmp = build3 (CASE_LABEL_EXPR, void_type_node, low, high, label);
995 gfc_add_expr_to_block (&body, tmp);
998 /* Add the statements for this case. */
999 tmp = gfc_trans_code (c->next);
1000 gfc_add_expr_to_block (&body, tmp);
1002 /* Break to the end of the construct. */
1003 tmp = build1_v (GOTO_EXPR, end_label);
1004 gfc_add_expr_to_block (&body, tmp);
1007 tmp = gfc_finish_block (&body);
1008 tmp = build3_v (SWITCH_EXPR, se.expr, tmp, NULL_TREE);
1009 gfc_add_expr_to_block (&block, tmp);
1011 tmp = build1_v (LABEL_EXPR, end_label);
1012 gfc_add_expr_to_block (&block, tmp);
1014 return gfc_finish_block (&block);
1018 /* Translate the SELECT CASE construct for LOGICAL case expressions.
1020 There are only two cases possible here, even though the standard
1021 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
1022 .FALSE., and DEFAULT.
1024 We never generate more than two blocks here. Instead, we always
1025 try to eliminate the DEFAULT case. This way, we can translate this
1026 kind of SELECT construct to a simple
1028 if {} else {};
1030 expression in GENERIC. */
1032 static tree
1033 gfc_trans_logical_select (gfc_code * code)
1035 gfc_code *c;
1036 gfc_code *t, *f, *d;
1037 gfc_case *cp;
1038 gfc_se se;
1039 stmtblock_t block;
1041 /* Assume we don't have any cases at all. */
1042 t = f = d = NULL;
1044 /* Now see which ones we actually do have. We can have at most two
1045 cases in a single case list: one for .TRUE. and one for .FALSE.
1046 The default case is always separate. If the cases for .TRUE. and
1047 .FALSE. are in the same case list, the block for that case list
1048 always executed, and we don't generate code a COND_EXPR. */
1049 for (c = code->block; c; c = c->block)
1051 for (cp = c->ext.case_list; cp; cp = cp->next)
1053 if (cp->low)
1055 if (cp->low->value.logical == 0) /* .FALSE. */
1056 f = c;
1057 else /* if (cp->value.logical != 0), thus .TRUE. */
1058 t = c;
1060 else
1061 d = c;
1065 /* Start a new block. */
1066 gfc_start_block (&block);
1068 /* Calculate the switch expression. We always need to do this
1069 because it may have side effects. */
1070 gfc_init_se (&se, NULL);
1071 gfc_conv_expr_val (&se, code->expr);
1072 gfc_add_block_to_block (&block, &se.pre);
1074 if (t == f && t != NULL)
1076 /* Cases for .TRUE. and .FALSE. are in the same block. Just
1077 translate the code for these cases, append it to the current
1078 block. */
1079 gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
1081 else
1083 tree true_tree, false_tree;
1085 true_tree = build_empty_stmt ();
1086 false_tree = build_empty_stmt ();
1088 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
1089 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
1090 make the missing case the default case. */
1091 if (t != NULL && f != NULL)
1092 d = NULL;
1093 else if (d != NULL)
1095 if (t == NULL)
1096 t = d;
1097 else
1098 f = d;
1101 /* Translate the code for each of these blocks, and append it to
1102 the current block. */
1103 if (t != NULL)
1104 true_tree = gfc_trans_code (t->next);
1106 if (f != NULL)
1107 false_tree = gfc_trans_code (f->next);
1109 gfc_add_expr_to_block (&block, build3_v (COND_EXPR, se.expr,
1110 true_tree, false_tree));
1113 return gfc_finish_block (&block);
1117 /* Translate the SELECT CASE construct for CHARACTER case expressions.
1118 Instead of generating compares and jumps, it is far simpler to
1119 generate a data structure describing the cases in order and call a
1120 library subroutine that locates the right case.
1121 This is particularly true because this is the only case where we
1122 might have to dispose of a temporary.
1123 The library subroutine returns a pointer to jump to or NULL if no
1124 branches are to be taken. */
1126 static tree
1127 gfc_trans_character_select (gfc_code *code)
1129 tree init, node, end_label, tmp, type, args, *labels;
1130 stmtblock_t block, body;
1131 gfc_case *cp, *d;
1132 gfc_code *c;
1133 gfc_se se;
1134 int i, n;
1136 static tree select_struct;
1137 static tree ss_string1, ss_string1_len;
1138 static tree ss_string2, ss_string2_len;
1139 static tree ss_target;
1141 if (select_struct == NULL)
1143 tree gfc_int4_type_node = gfc_get_int_type (4);
1145 select_struct = make_node (RECORD_TYPE);
1146 TYPE_NAME (select_struct) = get_identifier ("_jump_struct");
1148 #undef ADD_FIELD
1149 #define ADD_FIELD(NAME, TYPE) \
1150 ss_##NAME = gfc_add_field_to_struct \
1151 (&(TYPE_FIELDS (select_struct)), select_struct, \
1152 get_identifier (stringize(NAME)), TYPE)
1154 ADD_FIELD (string1, pchar_type_node);
1155 ADD_FIELD (string1_len, gfc_int4_type_node);
1157 ADD_FIELD (string2, pchar_type_node);
1158 ADD_FIELD (string2_len, gfc_int4_type_node);
1160 ADD_FIELD (target, pvoid_type_node);
1161 #undef ADD_FIELD
1163 gfc_finish_type (select_struct);
1166 cp = code->block->ext.case_list;
1167 while (cp->left != NULL)
1168 cp = cp->left;
1170 n = 0;
1171 for (d = cp; d; d = d->right)
1172 d->n = n++;
1174 if (n != 0)
1175 labels = gfc_getmem (n * sizeof (tree));
1176 else
1177 labels = NULL;
1179 for(i = 0; i < n; i++)
1181 labels[i] = gfc_build_label_decl (NULL_TREE);
1182 TREE_USED (labels[i]) = 1;
1183 /* TODO: The gimplifier should do this for us, but it has
1184 inadequacies when dealing with static initializers. */
1185 FORCED_LABEL (labels[i]) = 1;
1188 end_label = gfc_build_label_decl (NULL_TREE);
1190 /* Generate the body */
1191 gfc_start_block (&block);
1192 gfc_init_block (&body);
1194 for (c = code->block; c; c = c->block)
1196 for (d = c->ext.case_list; d; d = d->next)
1198 tmp = build1_v (LABEL_EXPR, labels[d->n]);
1199 gfc_add_expr_to_block (&body, tmp);
1202 tmp = gfc_trans_code (c->next);
1203 gfc_add_expr_to_block (&body, tmp);
1205 tmp = build1_v (GOTO_EXPR, end_label);
1206 gfc_add_expr_to_block (&body, tmp);
1209 /* Generate the structure describing the branches */
1210 init = NULL_TREE;
1211 i = 0;
1213 for(d = cp; d; d = d->right, i++)
1215 node = NULL_TREE;
1217 gfc_init_se (&se, NULL);
1219 if (d->low == NULL)
1221 node = tree_cons (ss_string1, null_pointer_node, node);
1222 node = tree_cons (ss_string1_len, integer_zero_node, node);
1224 else
1226 gfc_conv_expr_reference (&se, d->low);
1228 node = tree_cons (ss_string1, se.expr, node);
1229 node = tree_cons (ss_string1_len, se.string_length, node);
1232 if (d->high == NULL)
1234 node = tree_cons (ss_string2, null_pointer_node, node);
1235 node = tree_cons (ss_string2_len, integer_zero_node, node);
1237 else
1239 gfc_init_se (&se, NULL);
1240 gfc_conv_expr_reference (&se, d->high);
1242 node = tree_cons (ss_string2, se.expr, node);
1243 node = tree_cons (ss_string2_len, se.string_length, node);
1246 tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
1247 node = tree_cons (ss_target, tmp, node);
1249 tmp = build_constructor_from_list (select_struct, nreverse (node));
1250 init = tree_cons (NULL_TREE, tmp, init);
1253 type = build_array_type (select_struct, build_index_type
1254 (build_int_cst (NULL_TREE, n - 1)));
1256 init = build_constructor_from_list (type, nreverse(init));
1257 TREE_CONSTANT (init) = 1;
1258 TREE_INVARIANT (init) = 1;
1259 TREE_STATIC (init) = 1;
1260 /* Create a static variable to hold the jump table. */
1261 tmp = gfc_create_var (type, "jumptable");
1262 TREE_CONSTANT (tmp) = 1;
1263 TREE_INVARIANT (tmp) = 1;
1264 TREE_STATIC (tmp) = 1;
1265 DECL_INITIAL (tmp) = init;
1266 init = tmp;
1268 /* Build an argument list for the library call */
1269 init = gfc_build_addr_expr (pvoid_type_node, init);
1270 args = gfc_chainon_list (NULL_TREE, init);
1272 tmp = build_int_cst (NULL_TREE, n);
1273 args = gfc_chainon_list (args, tmp);
1275 tmp = gfc_build_addr_expr (pvoid_type_node, end_label);
1276 args = gfc_chainon_list (args, tmp);
1278 gfc_init_se (&se, NULL);
1279 gfc_conv_expr_reference (&se, code->expr);
1281 args = gfc_chainon_list (args, se.expr);
1282 args = gfc_chainon_list (args, se.string_length);
1284 gfc_add_block_to_block (&block, &se.pre);
1286 tmp = gfc_build_function_call (gfor_fndecl_select_string, args);
1287 tmp = build1 (GOTO_EXPR, void_type_node, tmp);
1288 gfc_add_expr_to_block (&block, tmp);
1290 tmp = gfc_finish_block (&body);
1291 gfc_add_expr_to_block (&block, tmp);
1292 tmp = build1_v (LABEL_EXPR, end_label);
1293 gfc_add_expr_to_block (&block, tmp);
1295 if (n != 0)
1296 gfc_free (labels);
1298 return gfc_finish_block (&block);
1302 /* Translate the three variants of the SELECT CASE construct.
1304 SELECT CASEs with INTEGER case expressions can be translated to an
1305 equivalent GENERIC switch statement, and for LOGICAL case
1306 expressions we build one or two if-else compares.
1308 SELECT CASEs with CHARACTER case expressions are a whole different
1309 story, because they don't exist in GENERIC. So we sort them and
1310 do a binary search at runtime.
1312 Fortran has no BREAK statement, and it does not allow jumps from
1313 one case block to another. That makes things a lot easier for
1314 the optimizers. */
1316 tree
1317 gfc_trans_select (gfc_code * code)
1319 gcc_assert (code && code->expr);
1321 /* Empty SELECT constructs are legal. */
1322 if (code->block == NULL)
1323 return build_empty_stmt ();
1325 /* Select the correct translation function. */
1326 switch (code->expr->ts.type)
1328 case BT_LOGICAL: return gfc_trans_logical_select (code);
1329 case BT_INTEGER: return gfc_trans_integer_select (code);
1330 case BT_CHARACTER: return gfc_trans_character_select (code);
1331 default:
1332 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
1333 /* Not reached */
1338 /* Generate the loops for a FORALL block. The normal loop format:
1339 count = (end - start + step) / step
1340 loopvar = start
1341 while (1)
1343 if (count <=0 )
1344 goto end_of_loop
1345 <body>
1346 loopvar += step
1347 count --
1349 end_of_loop: */
1351 static tree
1352 gfc_trans_forall_loop (forall_info *forall_tmp, int nvar, tree body, int mask_flag)
1354 int n;
1355 tree tmp;
1356 tree cond;
1357 stmtblock_t block;
1358 tree exit_label;
1359 tree count;
1360 tree var, start, end, step;
1361 iter_info *iter;
1363 iter = forall_tmp->this_loop;
1364 for (n = 0; n < nvar; n++)
1366 var = iter->var;
1367 start = iter->start;
1368 end = iter->end;
1369 step = iter->step;
1371 exit_label = gfc_build_label_decl (NULL_TREE);
1372 TREE_USED (exit_label) = 1;
1374 /* The loop counter. */
1375 count = gfc_create_var (TREE_TYPE (var), "count");
1377 /* The body of the loop. */
1378 gfc_init_block (&block);
1380 /* The exit condition. */
1381 cond = build2 (LE_EXPR, boolean_type_node, count, integer_zero_node);
1382 tmp = build1_v (GOTO_EXPR, exit_label);
1383 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1384 gfc_add_expr_to_block (&block, tmp);
1386 /* The main loop body. */
1387 gfc_add_expr_to_block (&block, body);
1389 /* Increment the loop variable. */
1390 tmp = build2 (PLUS_EXPR, TREE_TYPE (var), var, step);
1391 gfc_add_modify_expr (&block, var, tmp);
1393 /* Advance to the next mask element. Only do this for the
1394 innermost loop. */
1395 if (n == 0 && mask_flag && forall_tmp->mask)
1397 tree maskindex = forall_tmp->maskindex;
1398 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
1399 maskindex, gfc_index_one_node);
1400 gfc_add_modify_expr (&block, maskindex, tmp);
1403 /* Decrement the loop counter. */
1404 tmp = build2 (MINUS_EXPR, TREE_TYPE (var), count, gfc_index_one_node);
1405 gfc_add_modify_expr (&block, count, tmp);
1407 body = gfc_finish_block (&block);
1409 /* Loop var initialization. */
1410 gfc_init_block (&block);
1411 gfc_add_modify_expr (&block, var, start);
1413 /* Initialize maskindex counter. Only do this before the
1414 outermost loop. */
1415 if (n == nvar - 1 && mask_flag && forall_tmp->mask)
1416 gfc_add_modify_expr (&block, forall_tmp->maskindex,
1417 gfc_index_zero_node);
1419 /* Initialize the loop counter. */
1420 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (var), step, start);
1421 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (var), end, tmp);
1422 tmp = fold_build2 (TRUNC_DIV_EXPR, TREE_TYPE (var), tmp, step);
1423 gfc_add_modify_expr (&block, count, tmp);
1425 /* The loop expression. */
1426 tmp = build1_v (LOOP_EXPR, body);
1427 gfc_add_expr_to_block (&block, tmp);
1429 /* The exit label. */
1430 tmp = build1_v (LABEL_EXPR, exit_label);
1431 gfc_add_expr_to_block (&block, tmp);
1433 body = gfc_finish_block (&block);
1434 iter = iter->next;
1436 return body;
1440 /* Generate the body and loops according to MASK_FLAG and NEST_FLAG.
1441 if MASK_FLAG is nonzero, the body is controlled by maskes in forall
1442 nest, otherwise, the body is not controlled by maskes.
1443 if NEST_FLAG is nonzero, generate loops for nested forall, otherwise,
1444 only generate loops for the current forall level. */
1446 static tree
1447 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
1448 int mask_flag, int nest_flag)
1450 tree tmp;
1451 int nvar;
1452 forall_info *forall_tmp;
1453 tree pmask, mask, maskindex;
1455 forall_tmp = nested_forall_info;
1456 /* Generate loops for nested forall. */
1457 if (nest_flag)
1459 while (forall_tmp->next_nest != NULL)
1460 forall_tmp = forall_tmp->next_nest;
1461 while (forall_tmp != NULL)
1463 /* Generate body with masks' control. */
1464 if (mask_flag)
1466 pmask = forall_tmp->pmask;
1467 mask = forall_tmp->mask;
1468 maskindex = forall_tmp->maskindex;
1470 if (mask)
1472 /* If a mask was specified make the assignment conditional. */
1473 if (pmask)
1474 tmp = gfc_build_indirect_ref (mask);
1475 else
1476 tmp = mask;
1477 tmp = gfc_build_array_ref (tmp, maskindex);
1479 body = build3_v (COND_EXPR, tmp, body, build_empty_stmt ());
1482 nvar = forall_tmp->nvar;
1483 body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1484 forall_tmp = forall_tmp->outer;
1487 else
1489 nvar = forall_tmp->nvar;
1490 body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1493 return body;
1497 /* Allocate data for holding a temporary array. Returns either a local
1498 temporary array or a pointer variable. */
1500 static tree
1501 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
1502 tree elem_type)
1504 tree tmpvar;
1505 tree type;
1506 tree tmp;
1507 tree args;
1509 if (INTEGER_CST_P (size))
1511 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
1512 gfc_index_one_node);
1514 else
1515 tmp = NULL_TREE;
1517 type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1518 type = build_array_type (elem_type, type);
1519 if (gfc_can_put_var_on_stack (bytesize))
1521 gcc_assert (INTEGER_CST_P (size));
1522 tmpvar = gfc_create_var (type, "temp");
1523 *pdata = NULL_TREE;
1525 else
1527 tmpvar = gfc_create_var (build_pointer_type (type), "temp");
1528 *pdata = convert (pvoid_type_node, tmpvar);
1530 args = gfc_chainon_list (NULL_TREE, bytesize);
1531 if (gfc_index_integer_kind == 4)
1532 tmp = gfor_fndecl_internal_malloc;
1533 else if (gfc_index_integer_kind == 8)
1534 tmp = gfor_fndecl_internal_malloc64;
1535 else
1536 gcc_unreachable ();
1537 tmp = gfc_build_function_call (tmp, args);
1538 tmp = convert (TREE_TYPE (tmpvar), tmp);
1539 gfc_add_modify_expr (pblock, tmpvar, tmp);
1541 return tmpvar;
1545 /* Generate codes to copy the temporary to the actual lhs. */
1547 static tree
1548 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
1549 tree count1, tree wheremask)
1551 gfc_ss *lss;
1552 gfc_se lse, rse;
1553 stmtblock_t block, body;
1554 gfc_loopinfo loop1;
1555 tree tmp, tmp2;
1556 tree wheremaskexpr;
1558 /* Walk the lhs. */
1559 lss = gfc_walk_expr (expr);
1561 if (lss == gfc_ss_terminator)
1563 gfc_start_block (&block);
1565 gfc_init_se (&lse, NULL);
1567 /* Translate the expression. */
1568 gfc_conv_expr (&lse, expr);
1570 /* Form the expression for the temporary. */
1571 tmp = gfc_build_array_ref (tmp1, count1);
1573 /* Use the scalar assignment as is. */
1574 gfc_add_block_to_block (&block, &lse.pre);
1575 gfc_add_modify_expr (&block, lse.expr, tmp);
1576 gfc_add_block_to_block (&block, &lse.post);
1578 /* Increment the count1. */
1579 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (count1), count1,
1580 gfc_index_one_node);
1581 gfc_add_modify_expr (&block, count1, tmp);
1583 tmp = gfc_finish_block (&block);
1585 else
1587 gfc_start_block (&block);
1589 gfc_init_loopinfo (&loop1);
1590 gfc_init_se (&rse, NULL);
1591 gfc_init_se (&lse, NULL);
1593 /* Associate the lss with the loop. */
1594 gfc_add_ss_to_loop (&loop1, lss);
1596 /* Calculate the bounds of the scalarization. */
1597 gfc_conv_ss_startstride (&loop1);
1598 /* Setup the scalarizing loops. */
1599 gfc_conv_loop_setup (&loop1);
1601 gfc_mark_ss_chain_used (lss, 1);
1603 /* Start the scalarized loop body. */
1604 gfc_start_scalarized_body (&loop1, &body);
1606 /* Setup the gfc_se structures. */
1607 gfc_copy_loopinfo_to_se (&lse, &loop1);
1608 lse.ss = lss;
1610 /* Form the expression of the temporary. */
1611 if (lss != gfc_ss_terminator)
1612 rse.expr = gfc_build_array_ref (tmp1, count1);
1613 /* Translate expr. */
1614 gfc_conv_expr (&lse, expr);
1616 /* Use the scalar assignment. */
1617 tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
1619 /* Form the mask expression according to the mask tree list. */
1620 if (wheremask)
1622 wheremaskexpr = gfc_build_array_ref (wheremask, count3);
1623 tmp2 = TREE_CHAIN (wheremask);
1624 while (tmp2)
1626 tmp1 = gfc_build_array_ref (tmp2, count3);
1627 wheremaskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
1628 wheremaskexpr, tmp1);
1629 tmp2 = TREE_CHAIN (tmp2);
1631 tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1634 gfc_add_expr_to_block (&body, tmp);
1636 /* Increment count1. */
1637 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1638 count1, gfc_index_one_node);
1639 gfc_add_modify_expr (&body, count1, tmp);
1641 /* Increment count3. */
1642 if (count3)
1644 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1645 count3, gfc_index_one_node);
1646 gfc_add_modify_expr (&body, count3, tmp);
1649 /* Generate the copying loops. */
1650 gfc_trans_scalarizing_loops (&loop1, &body);
1651 gfc_add_block_to_block (&block, &loop1.pre);
1652 gfc_add_block_to_block (&block, &loop1.post);
1653 gfc_cleanup_loop (&loop1);
1655 tmp = gfc_finish_block (&block);
1657 return tmp;
1661 /* Generate codes to copy rhs to the temporary. TMP1 is the address of temporary
1662 LSS and RSS are formed in function compute_inner_temp_size(), and should
1663 not be freed. */
1665 static tree
1666 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree count3,
1667 tree count1, gfc_ss *lss, gfc_ss *rss,
1668 tree wheremask)
1670 stmtblock_t block, body1;
1671 gfc_loopinfo loop;
1672 gfc_se lse;
1673 gfc_se rse;
1674 tree tmp, tmp2;
1675 tree wheremaskexpr;
1677 gfc_start_block (&block);
1679 gfc_init_se (&rse, NULL);
1680 gfc_init_se (&lse, NULL);
1682 if (lss == gfc_ss_terminator)
1684 gfc_init_block (&body1);
1685 gfc_conv_expr (&rse, expr2);
1686 lse.expr = gfc_build_array_ref (tmp1, count1);
1688 else
1690 /* Initialize the loop. */
1691 gfc_init_loopinfo (&loop);
1693 /* We may need LSS to determine the shape of the expression. */
1694 gfc_add_ss_to_loop (&loop, lss);
1695 gfc_add_ss_to_loop (&loop, rss);
1697 gfc_conv_ss_startstride (&loop);
1698 gfc_conv_loop_setup (&loop);
1700 gfc_mark_ss_chain_used (rss, 1);
1701 /* Start the loop body. */
1702 gfc_start_scalarized_body (&loop, &body1);
1704 /* Translate the expression. */
1705 gfc_copy_loopinfo_to_se (&rse, &loop);
1706 rse.ss = rss;
1707 gfc_conv_expr (&rse, expr2);
1709 /* Form the expression of the temporary. */
1710 lse.expr = gfc_build_array_ref (tmp1, count1);
1713 /* Use the scalar assignment. */
1714 tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts.type);
1716 /* Form the mask expression according to the mask tree list. */
1717 if (wheremask)
1719 wheremaskexpr = gfc_build_array_ref (wheremask, count3);
1720 tmp2 = TREE_CHAIN (wheremask);
1721 while (tmp2)
1723 tmp1 = gfc_build_array_ref (tmp2, count3);
1724 wheremaskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
1725 wheremaskexpr, tmp1);
1726 tmp2 = TREE_CHAIN (tmp2);
1728 tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1731 gfc_add_expr_to_block (&body1, tmp);
1733 if (lss == gfc_ss_terminator)
1735 gfc_add_block_to_block (&block, &body1);
1737 /* Increment count1. */
1738 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (count1), count1,
1739 gfc_index_one_node);
1740 gfc_add_modify_expr (&block, count1, tmp);
1742 else
1744 /* Increment count1. */
1745 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1746 count1, gfc_index_one_node);
1747 gfc_add_modify_expr (&body1, count1, tmp);
1749 /* Increment count3. */
1750 if (count3)
1752 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1753 count3, gfc_index_one_node);
1754 gfc_add_modify_expr (&body1, count3, tmp);
1757 /* Generate the copying loops. */
1758 gfc_trans_scalarizing_loops (&loop, &body1);
1760 gfc_add_block_to_block (&block, &loop.pre);
1761 gfc_add_block_to_block (&block, &loop.post);
1763 gfc_cleanup_loop (&loop);
1764 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
1765 as tree nodes in SS may not be valid in different scope. */
1768 tmp = gfc_finish_block (&block);
1769 return tmp;
1773 /* Calculate the size of temporary needed in the assignment inside forall.
1774 LSS and RSS are filled in this function. */
1776 static tree
1777 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
1778 stmtblock_t * pblock,
1779 gfc_ss **lss, gfc_ss **rss)
1781 gfc_loopinfo loop;
1782 tree size;
1783 int i;
1784 tree tmp;
1786 *lss = gfc_walk_expr (expr1);
1787 *rss = NULL;
1789 size = gfc_index_one_node;
1790 if (*lss != gfc_ss_terminator)
1792 gfc_init_loopinfo (&loop);
1794 /* Walk the RHS of the expression. */
1795 *rss = gfc_walk_expr (expr2);
1796 if (*rss == gfc_ss_terminator)
1798 /* The rhs is scalar. Add a ss for the expression. */
1799 *rss = gfc_get_ss ();
1800 (*rss)->next = gfc_ss_terminator;
1801 (*rss)->type = GFC_SS_SCALAR;
1802 (*rss)->expr = expr2;
1805 /* Associate the SS with the loop. */
1806 gfc_add_ss_to_loop (&loop, *lss);
1807 /* We don't actually need to add the rhs at this point, but it might
1808 make guessing the loop bounds a bit easier. */
1809 gfc_add_ss_to_loop (&loop, *rss);
1811 /* We only want the shape of the expression, not rest of the junk
1812 generated by the scalarizer. */
1813 loop.array_parameter = 1;
1815 /* Calculate the bounds of the scalarization. */
1816 gfc_conv_ss_startstride (&loop);
1817 gfc_conv_loop_setup (&loop);
1819 /* Figure out how many elements we need. */
1820 for (i = 0; i < loop.dimen; i++)
1822 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1823 gfc_index_one_node, loop.from[i]);
1824 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1825 tmp, loop.to[i]);
1826 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
1828 gfc_add_block_to_block (pblock, &loop.pre);
1829 size = gfc_evaluate_now (size, pblock);
1830 gfc_add_block_to_block (pblock, &loop.post);
1832 /* TODO: write a function that cleans up a loopinfo without freeing
1833 the SS chains. Currently a NOP. */
1836 return size;
1840 /* Calculate the overall iterator number of the nested forall construct. */
1842 static tree
1843 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
1844 stmtblock_t *inner_size_body, stmtblock_t *block)
1846 tree tmp, number;
1847 stmtblock_t body;
1849 /* TODO: optimizing the computing process. */
1850 number = gfc_create_var (gfc_array_index_type, "num");
1851 gfc_add_modify_expr (block, number, gfc_index_zero_node);
1853 gfc_start_block (&body);
1854 if (inner_size_body)
1855 gfc_add_block_to_block (&body, inner_size_body);
1856 if (nested_forall_info)
1857 tmp = build2 (PLUS_EXPR, gfc_array_index_type, number,
1858 inner_size);
1859 else
1860 tmp = inner_size;
1861 gfc_add_modify_expr (&body, number, tmp);
1862 tmp = gfc_finish_block (&body);
1864 /* Generate loops. */
1865 if (nested_forall_info != NULL)
1866 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 0, 1);
1868 gfc_add_expr_to_block (block, tmp);
1870 return number;
1874 /* Allocate temporary for forall construct. SIZE is the size of temporary
1875 needed. PTEMP1 is returned for space free. */
1877 static tree
1878 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
1879 tree * ptemp1)
1881 tree unit;
1882 tree temp1;
1883 tree tmp;
1884 tree bytesize;
1886 unit = TYPE_SIZE_UNIT (type);
1887 bytesize = fold_build2 (MULT_EXPR, gfc_array_index_type, size, unit);
1889 *ptemp1 = NULL;
1890 temp1 = gfc_do_allocate (bytesize, size, ptemp1, block, type);
1892 if (*ptemp1)
1893 tmp = gfc_build_indirect_ref (temp1);
1894 else
1895 tmp = temp1;
1897 return tmp;
1901 /* Allocate temporary for forall construct according to the information in
1902 nested_forall_info. INNER_SIZE is the size of temporary needed in the
1903 assignment inside forall. PTEMP1 is returned for space free. */
1905 static tree
1906 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
1907 tree inner_size, stmtblock_t * inner_size_body,
1908 stmtblock_t * block, tree * ptemp1)
1910 tree size;
1912 /* Calculate the total size of temporary needed in forall construct. */
1913 size = compute_overall_iter_number (nested_forall_info, inner_size,
1914 inner_size_body, block);
1916 return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
1920 /* Handle assignments inside forall which need temporary.
1922 forall (i=start:end:stride; maskexpr)
1923 e<i> = f<i>
1924 end forall
1925 (where e,f<i> are arbitrary expressions possibly involving i
1926 and there is a dependency between e<i> and f<i>)
1927 Translates to:
1928 masktmp(:) = maskexpr(:)
1930 maskindex = 0;
1931 count1 = 0;
1932 num = 0;
1933 for (i = start; i <= end; i += stride)
1934 num += SIZE (f<i>)
1935 count1 = 0;
1936 ALLOCATE (tmp(num))
1937 for (i = start; i <= end; i += stride)
1939 if (masktmp[maskindex++])
1940 tmp[count1++] = f<i>
1942 maskindex = 0;
1943 count1 = 0;
1944 for (i = start; i <= end; i += stride)
1946 if (masktmp[maskindex++])
1947 e<i> = tmp[count1++]
1949 DEALLOCATE (tmp)
1951 static void
1952 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2, tree wheremask,
1953 forall_info * nested_forall_info,
1954 stmtblock_t * block)
1956 tree type;
1957 tree inner_size;
1958 gfc_ss *lss, *rss;
1959 tree count, count1;
1960 tree tmp, tmp1;
1961 tree ptemp1;
1962 stmtblock_t inner_size_body;
1964 /* Create vars. count1 is the current iterator number of the nested
1965 forall. */
1966 count1 = gfc_create_var (gfc_array_index_type, "count1");
1968 /* Count is the wheremask index. */
1969 if (wheremask)
1971 count = gfc_create_var (gfc_array_index_type, "count");
1972 gfc_add_modify_expr (block, count, gfc_index_zero_node);
1974 else
1975 count = NULL;
1977 /* Initialize count1. */
1978 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
1980 /* Calculate the size of temporary needed in the assignment. Return loop, lss
1981 and rss which are used in function generate_loop_for_rhs_to_temp(). */
1982 gfc_init_block (&inner_size_body);
1983 inner_size = compute_inner_temp_size (expr1, expr2, &inner_size_body,
1984 &lss, &rss);
1986 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
1987 type = gfc_typenode_for_spec (&expr1->ts);
1989 /* Allocate temporary for nested forall construct according to the
1990 information in nested_forall_info and inner_size. */
1991 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type, inner_size,
1992 &inner_size_body, block, &ptemp1);
1994 /* Generate codes to copy rhs to the temporary . */
1995 tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, count, count1, lss, rss,
1996 wheremask);
1998 /* Generate body and loops according to the information in
1999 nested_forall_info. */
2000 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2001 gfc_add_expr_to_block (block, tmp);
2003 /* Reset count1. */
2004 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
2006 /* Reset count. */
2007 if (wheremask)
2008 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2010 /* Generate codes to copy the temporary to lhs. */
2011 tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1, wheremask);
2013 /* Generate body and loops according to the information in
2014 nested_forall_info. */
2015 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2016 gfc_add_expr_to_block (block, tmp);
2018 if (ptemp1)
2020 /* Free the temporary. */
2021 tmp = gfc_chainon_list (NULL_TREE, ptemp1);
2022 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2023 gfc_add_expr_to_block (block, tmp);
2028 /* Translate pointer assignment inside FORALL which need temporary. */
2030 static void
2031 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
2032 forall_info * nested_forall_info,
2033 stmtblock_t * block)
2035 tree type;
2036 tree inner_size;
2037 gfc_ss *lss, *rss;
2038 gfc_se lse;
2039 gfc_se rse;
2040 gfc_ss_info *info;
2041 gfc_loopinfo loop;
2042 tree desc;
2043 tree parm;
2044 tree parmtype;
2045 stmtblock_t body;
2046 tree count;
2047 tree tmp, tmp1, ptemp1;
2049 count = gfc_create_var (gfc_array_index_type, "count");
2050 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2052 inner_size = integer_one_node;
2053 lss = gfc_walk_expr (expr1);
2054 rss = gfc_walk_expr (expr2);
2055 if (lss == gfc_ss_terminator)
2057 type = gfc_typenode_for_spec (&expr1->ts);
2058 type = build_pointer_type (type);
2060 /* Allocate temporary for nested forall construct according to the
2061 information in nested_forall_info and inner_size. */
2062 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
2063 inner_size, NULL, block, &ptemp1);
2064 gfc_start_block (&body);
2065 gfc_init_se (&lse, NULL);
2066 lse.expr = gfc_build_array_ref (tmp1, count);
2067 gfc_init_se (&rse, NULL);
2068 rse.want_pointer = 1;
2069 gfc_conv_expr (&rse, expr2);
2070 gfc_add_block_to_block (&body, &rse.pre);
2071 gfc_add_modify_expr (&body, lse.expr, rse.expr);
2072 gfc_add_block_to_block (&body, &rse.post);
2074 /* Increment count. */
2075 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2076 count, gfc_index_one_node);
2077 gfc_add_modify_expr (&body, count, tmp);
2079 tmp = gfc_finish_block (&body);
2081 /* Generate body and loops according to the information in
2082 nested_forall_info. */
2083 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2084 gfc_add_expr_to_block (block, tmp);
2086 /* Reset count. */
2087 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2089 gfc_start_block (&body);
2090 gfc_init_se (&lse, NULL);
2091 gfc_init_se (&rse, NULL);
2092 rse.expr = gfc_build_array_ref (tmp1, count);
2093 lse.want_pointer = 1;
2094 gfc_conv_expr (&lse, expr1);
2095 gfc_add_block_to_block (&body, &lse.pre);
2096 gfc_add_modify_expr (&body, lse.expr, rse.expr);
2097 gfc_add_block_to_block (&body, &lse.post);
2098 /* Increment count. */
2099 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2100 count, gfc_index_one_node);
2101 gfc_add_modify_expr (&body, count, tmp);
2102 tmp = gfc_finish_block (&body);
2104 /* Generate body and loops according to the information in
2105 nested_forall_info. */
2106 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2107 gfc_add_expr_to_block (block, tmp);
2109 else
2111 gfc_init_loopinfo (&loop);
2113 /* Associate the SS with the loop. */
2114 gfc_add_ss_to_loop (&loop, rss);
2116 /* Setup the scalarizing loops and bounds. */
2117 gfc_conv_ss_startstride (&loop);
2119 gfc_conv_loop_setup (&loop);
2121 info = &rss->data.info;
2122 desc = info->descriptor;
2124 /* Make a new descriptor. */
2125 parmtype = gfc_get_element_type (TREE_TYPE (desc));
2126 parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
2127 loop.from, loop.to, 1);
2129 /* Allocate temporary for nested forall construct. */
2130 tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
2131 inner_size, NULL, block, &ptemp1);
2132 gfc_start_block (&body);
2133 gfc_init_se (&lse, NULL);
2134 lse.expr = gfc_build_array_ref (tmp1, count);
2135 lse.direct_byref = 1;
2136 rss = gfc_walk_expr (expr2);
2137 gfc_conv_expr_descriptor (&lse, expr2, rss);
2139 gfc_add_block_to_block (&body, &lse.pre);
2140 gfc_add_block_to_block (&body, &lse.post);
2142 /* Increment count. */
2143 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2144 count, gfc_index_one_node);
2145 gfc_add_modify_expr (&body, count, tmp);
2147 tmp = gfc_finish_block (&body);
2149 /* Generate body and loops according to the information in
2150 nested_forall_info. */
2151 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2152 gfc_add_expr_to_block (block, tmp);
2154 /* Reset count. */
2155 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2157 parm = gfc_build_array_ref (tmp1, count);
2158 lss = gfc_walk_expr (expr1);
2159 gfc_init_se (&lse, NULL);
2160 gfc_conv_expr_descriptor (&lse, expr1, lss);
2161 gfc_add_modify_expr (&lse.pre, lse.expr, parm);
2162 gfc_start_block (&body);
2163 gfc_add_block_to_block (&body, &lse.pre);
2164 gfc_add_block_to_block (&body, &lse.post);
2166 /* Increment count. */
2167 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2168 count, gfc_index_one_node);
2169 gfc_add_modify_expr (&body, count, tmp);
2171 tmp = gfc_finish_block (&body);
2173 tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2174 gfc_add_expr_to_block (block, tmp);
2176 /* Free the temporary. */
2177 if (ptemp1)
2179 tmp = gfc_chainon_list (NULL_TREE, ptemp1);
2180 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2181 gfc_add_expr_to_block (block, tmp);
2186 /* FORALL and WHERE statements are really nasty, especially when you nest
2187 them. All the rhs of a forall assignment must be evaluated before the
2188 actual assignments are performed. Presumably this also applies to all the
2189 assignments in an inner where statement. */
2191 /* Generate code for a FORALL statement. Any temporaries are allocated as a
2192 linear array, relying on the fact that we process in the same order in all
2193 loops.
2195 forall (i=start:end:stride; maskexpr)
2196 e<i> = f<i>
2197 g<i> = h<i>
2198 end forall
2199 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
2200 Translates to:
2201 count = ((end + 1 - start) / stride)
2202 masktmp(:) = maskexpr(:)
2204 maskindex = 0;
2205 for (i = start; i <= end; i += stride)
2207 if (masktmp[maskindex++])
2208 e<i> = f<i>
2210 maskindex = 0;
2211 for (i = start; i <= end; i += stride)
2213 if (masktmp[maskindex++])
2214 g<i> = h<i>
2217 Note that this code only works when there are no dependencies.
2218 Forall loop with array assignments and data dependencies are a real pain,
2219 because the size of the temporary cannot always be determined before the
2220 loop is executed. This problem is compounded by the presence of nested
2221 FORALL constructs.
2224 static tree
2225 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
2227 stmtblock_t block;
2228 stmtblock_t body;
2229 tree *var;
2230 tree *start;
2231 tree *end;
2232 tree *step;
2233 gfc_expr **varexpr;
2234 tree tmp;
2235 tree assign;
2236 tree size;
2237 tree bytesize;
2238 tree tmpvar;
2239 tree sizevar;
2240 tree lenvar;
2241 tree maskindex;
2242 tree mask;
2243 tree pmask;
2244 int n;
2245 int nvar;
2246 int need_temp;
2247 gfc_forall_iterator *fa;
2248 gfc_se se;
2249 gfc_code *c;
2250 gfc_saved_var *saved_vars;
2251 iter_info *this_forall, *iter_tmp;
2252 forall_info *info, *forall_tmp;
2253 temporary_list *temp;
2255 gfc_start_block (&block);
2257 n = 0;
2258 /* Count the FORALL index number. */
2259 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
2260 n++;
2261 nvar = n;
2263 /* Allocate the space for var, start, end, step, varexpr. */
2264 var = (tree *) gfc_getmem (nvar * sizeof (tree));
2265 start = (tree *) gfc_getmem (nvar * sizeof (tree));
2266 end = (tree *) gfc_getmem (nvar * sizeof (tree));
2267 step = (tree *) gfc_getmem (nvar * sizeof (tree));
2268 varexpr = (gfc_expr **) gfc_getmem (nvar * sizeof (gfc_expr *));
2269 saved_vars = (gfc_saved_var *) gfc_getmem (nvar * sizeof (gfc_saved_var));
2271 /* Allocate the space for info. */
2272 info = (forall_info *) gfc_getmem (sizeof (forall_info));
2273 n = 0;
2274 for (fa = code->ext.forall_iterator; fa; fa = fa->next)
2276 gfc_symbol *sym = fa->var->symtree->n.sym;
2278 /* allocate space for this_forall. */
2279 this_forall = (iter_info *) gfc_getmem (sizeof (iter_info));
2281 /* Create a temporary variable for the FORALL index. */
2282 tmp = gfc_typenode_for_spec (&sym->ts);
2283 var[n] = gfc_create_var (tmp, sym->name);
2284 gfc_shadow_sym (sym, var[n], &saved_vars[n]);
2286 /* Record it in this_forall. */
2287 this_forall->var = var[n];
2289 /* Replace the index symbol's backend_decl with the temporary decl. */
2290 sym->backend_decl = var[n];
2292 /* Work out the start, end and stride for the loop. */
2293 gfc_init_se (&se, NULL);
2294 gfc_conv_expr_val (&se, fa->start);
2295 /* Record it in this_forall. */
2296 this_forall->start = se.expr;
2297 gfc_add_block_to_block (&block, &se.pre);
2298 start[n] = se.expr;
2300 gfc_init_se (&se, NULL);
2301 gfc_conv_expr_val (&se, fa->end);
2302 /* Record it in this_forall. */
2303 this_forall->end = se.expr;
2304 gfc_make_safe_expr (&se);
2305 gfc_add_block_to_block (&block, &se.pre);
2306 end[n] = se.expr;
2308 gfc_init_se (&se, NULL);
2309 gfc_conv_expr_val (&se, fa->stride);
2310 /* Record it in this_forall. */
2311 this_forall->step = se.expr;
2312 gfc_make_safe_expr (&se);
2313 gfc_add_block_to_block (&block, &se.pre);
2314 step[n] = se.expr;
2316 /* Set the NEXT field of this_forall to NULL. */
2317 this_forall->next = NULL;
2318 /* Link this_forall to the info construct. */
2319 if (info->this_loop == NULL)
2320 info->this_loop = this_forall;
2321 else
2323 iter_tmp = info->this_loop;
2324 while (iter_tmp->next != NULL)
2325 iter_tmp = iter_tmp->next;
2326 iter_tmp->next = this_forall;
2329 n++;
2331 nvar = n;
2333 /* Work out the number of elements in the mask array. */
2334 tmpvar = NULL_TREE;
2335 lenvar = NULL_TREE;
2336 size = gfc_index_one_node;
2337 sizevar = NULL_TREE;
2339 for (n = 0; n < nvar; n++)
2341 if (lenvar && TREE_TYPE (lenvar) != TREE_TYPE (start[n]))
2342 lenvar = NULL_TREE;
2344 /* size = (end + step - start) / step. */
2345 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (start[n]),
2346 step[n], start[n]);
2347 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (end[n]), end[n], tmp);
2349 tmp = fold_build2 (FLOOR_DIV_EXPR, TREE_TYPE (tmp), tmp, step[n]);
2350 tmp = convert (gfc_array_index_type, tmp);
2352 size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
2355 /* Record the nvar and size of current forall level. */
2356 info->nvar = nvar;
2357 info->size = size;
2359 /* Link the current forall level to nested_forall_info. */
2360 forall_tmp = nested_forall_info;
2361 if (forall_tmp == NULL)
2362 nested_forall_info = info;
2363 else
2365 while (forall_tmp->next_nest != NULL)
2366 forall_tmp = forall_tmp->next_nest;
2367 info->outer = forall_tmp;
2368 forall_tmp->next_nest = info;
2371 /* Copy the mask into a temporary variable if required.
2372 For now we assume a mask temporary is needed. */
2373 if (code->expr)
2375 /* As the mask array can be very big, prefer compact
2376 boolean types. */
2377 tree smallest_boolean_type_node
2378 = gfc_get_logical_type (gfc_logical_kinds[0].kind);
2380 /* Allocate the mask temporary. */
2381 bytesize = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
2382 TYPE_SIZE_UNIT (smallest_boolean_type_node));
2384 mask = gfc_do_allocate (bytesize, size, &pmask, &block,
2385 smallest_boolean_type_node);
2387 maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
2388 /* Record them in the info structure. */
2389 info->pmask = pmask;
2390 info->mask = mask;
2391 info->maskindex = maskindex;
2393 gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2395 /* Start of mask assignment loop body. */
2396 gfc_start_block (&body);
2398 /* Evaluate the mask expression. */
2399 gfc_init_se (&se, NULL);
2400 gfc_conv_expr_val (&se, code->expr);
2401 gfc_add_block_to_block (&body, &se.pre);
2403 /* Store the mask. */
2404 se.expr = convert (smallest_boolean_type_node, se.expr);
2406 if (pmask)
2407 tmp = gfc_build_indirect_ref (mask);
2408 else
2409 tmp = mask;
2410 tmp = gfc_build_array_ref (tmp, maskindex);
2411 gfc_add_modify_expr (&body, tmp, se.expr);
2413 /* Advance to the next mask element. */
2414 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2415 maskindex, gfc_index_one_node);
2416 gfc_add_modify_expr (&body, maskindex, tmp);
2418 /* Generate the loops. */
2419 tmp = gfc_finish_block (&body);
2420 tmp = gfc_trans_nested_forall_loop (info, tmp, 0, 0);
2421 gfc_add_expr_to_block (&block, tmp);
2423 else
2425 /* No mask was specified. */
2426 maskindex = NULL_TREE;
2427 mask = pmask = NULL_TREE;
2430 c = code->block->next;
2432 /* TODO: loop merging in FORALL statements. */
2433 /* Now that we've got a copy of the mask, generate the assignment loops. */
2434 while (c)
2436 switch (c->op)
2438 case EXEC_ASSIGN:
2439 /* A scalar or array assignment. */
2440 need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
2441 /* Temporaries due to array assignment data dependencies introduce
2442 no end of problems. */
2443 if (need_temp)
2444 gfc_trans_assign_need_temp (c->expr, c->expr2, NULL,
2445 nested_forall_info, &block);
2446 else
2448 /* Use the normal assignment copying routines. */
2449 assign = gfc_trans_assignment (c->expr, c->expr2);
2451 /* Generate body and loops. */
2452 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1, 1);
2453 gfc_add_expr_to_block (&block, tmp);
2456 break;
2458 case EXEC_WHERE:
2460 /* Translate WHERE or WHERE construct nested in FORALL. */
2461 temp = NULL;
2462 gfc_trans_where_2 (c, NULL, NULL, nested_forall_info, &block, &temp);
2464 while (temp)
2466 tree args;
2467 temporary_list *p;
2469 /* Free the temporary. */
2470 args = gfc_chainon_list (NULL_TREE, temp->temporary);
2471 tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
2472 gfc_add_expr_to_block (&block, tmp);
2474 p = temp;
2475 temp = temp->next;
2476 gfc_free (p);
2479 break;
2481 /* Pointer assignment inside FORALL. */
2482 case EXEC_POINTER_ASSIGN:
2483 need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
2484 if (need_temp)
2485 gfc_trans_pointer_assign_need_temp (c->expr, c->expr2,
2486 nested_forall_info, &block);
2487 else
2489 /* Use the normal assignment copying routines. */
2490 assign = gfc_trans_pointer_assignment (c->expr, c->expr2);
2492 /* Generate body and loops. */
2493 tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign,
2494 1, 1);
2495 gfc_add_expr_to_block (&block, tmp);
2497 break;
2499 case EXEC_FORALL:
2500 tmp = gfc_trans_forall_1 (c, nested_forall_info);
2501 gfc_add_expr_to_block (&block, tmp);
2502 break;
2504 default:
2505 gcc_unreachable ();
2508 c = c->next;
2511 /* Restore the original index variables. */
2512 for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
2513 gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
2515 /* Free the space for var, start, end, step, varexpr. */
2516 gfc_free (var);
2517 gfc_free (start);
2518 gfc_free (end);
2519 gfc_free (step);
2520 gfc_free (varexpr);
2521 gfc_free (saved_vars);
2523 if (pmask)
2525 /* Free the temporary for the mask. */
2526 tmp = gfc_chainon_list (NULL_TREE, pmask);
2527 tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2528 gfc_add_expr_to_block (&block, tmp);
2530 if (maskindex)
2531 pushdecl (maskindex);
2533 return gfc_finish_block (&block);
2537 /* Translate the FORALL statement or construct. */
2539 tree gfc_trans_forall (gfc_code * code)
2541 return gfc_trans_forall_1 (code, NULL);
2545 /* Evaluate the WHERE mask expression, copy its value to a temporary.
2546 If the WHERE construct is nested in FORALL, compute the overall temporary
2547 needed by the WHERE mask expression multiplied by the iterator number of
2548 the nested forall.
2549 ME is the WHERE mask expression.
2550 MASK is the temporary which value is mask's value.
2551 NMASK is another temporary which value is !mask.
2552 TEMP records the temporary's address allocated in this function in order to
2553 free them outside this function.
2554 MASK, NMASK and TEMP are all OUT arguments. */
2556 static tree
2557 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
2558 tree * mask, tree * nmask, temporary_list ** temp,
2559 stmtblock_t * block)
2561 tree tmp, tmp1;
2562 gfc_ss *lss, *rss;
2563 gfc_loopinfo loop;
2564 tree ptemp1, ntmp, ptemp2;
2565 tree inner_size, size;
2566 stmtblock_t body, body1, inner_size_body;
2567 gfc_se lse, rse;
2568 tree count;
2569 tree tmpexpr;
2571 gfc_init_loopinfo (&loop);
2573 /* Calculate the size of temporary needed by the mask-expr. */
2574 gfc_init_block (&inner_size_body);
2575 inner_size = compute_inner_temp_size (me, me, &inner_size_body, &lss, &rss);
2577 /* Calculate the total size of temporary needed. */
2578 size = compute_overall_iter_number (nested_forall_info, inner_size,
2579 &inner_size_body, block);
2581 /* Allocate temporary for where mask. */
2582 tmp = allocate_temp_for_forall_nest_1 (boolean_type_node, size, block,
2583 &ptemp1);
2584 /* Record the temporary address in order to free it later. */
2585 if (ptemp1)
2587 temporary_list *tempo;
2588 tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2589 tempo->temporary = ptemp1;
2590 tempo->next = *temp;
2591 *temp = tempo;
2594 /* Allocate temporary for !mask. */
2595 ntmp = allocate_temp_for_forall_nest_1 (boolean_type_node, size, block,
2596 &ptemp2);
2597 /* Record the temporary in order to free it later. */
2598 if (ptemp2)
2600 temporary_list *tempo;
2601 tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2602 tempo->temporary = ptemp2;
2603 tempo->next = *temp;
2604 *temp = tempo;
2607 /* Variable to index the temporary. */
2608 count = gfc_create_var (gfc_array_index_type, "count");
2609 /* Initialize count. */
2610 gfc_add_modify_expr (block, count, gfc_index_zero_node);
2612 gfc_start_block (&body);
2614 gfc_init_se (&rse, NULL);
2615 gfc_init_se (&lse, NULL);
2617 if (lss == gfc_ss_terminator)
2619 gfc_init_block (&body1);
2621 else
2623 /* Initialize the loop. */
2624 gfc_init_loopinfo (&loop);
2626 /* We may need LSS to determine the shape of the expression. */
2627 gfc_add_ss_to_loop (&loop, lss);
2628 gfc_add_ss_to_loop (&loop, rss);
2630 gfc_conv_ss_startstride (&loop);
2631 gfc_conv_loop_setup (&loop);
2633 gfc_mark_ss_chain_used (rss, 1);
2634 /* Start the loop body. */
2635 gfc_start_scalarized_body (&loop, &body1);
2637 /* Translate the expression. */
2638 gfc_copy_loopinfo_to_se (&rse, &loop);
2639 rse.ss = rss;
2640 gfc_conv_expr (&rse, me);
2642 /* Form the expression of the temporary. */
2643 lse.expr = gfc_build_array_ref (tmp, count);
2644 tmpexpr = gfc_build_array_ref (ntmp, count);
2646 /* Use the scalar assignment to fill temporary TMP. */
2647 tmp1 = gfc_trans_scalar_assign (&lse, &rse, me->ts.type);
2648 gfc_add_expr_to_block (&body1, tmp1);
2650 /* Fill temporary NTMP. */
2651 tmp1 = build1 (TRUTH_NOT_EXPR, TREE_TYPE (lse.expr), lse.expr);
2652 gfc_add_modify_expr (&body1, tmpexpr, tmp1);
2654 if (lss == gfc_ss_terminator)
2656 gfc_add_block_to_block (&body, &body1);
2658 else
2660 /* Increment count. */
2661 tmp1 = fold_build2 (PLUS_EXPR, gfc_array_index_type, count,
2662 gfc_index_one_node);
2663 gfc_add_modify_expr (&body1, count, tmp1);
2665 /* Generate the copying loops. */
2666 gfc_trans_scalarizing_loops (&loop, &body1);
2668 gfc_add_block_to_block (&body, &loop.pre);
2669 gfc_add_block_to_block (&body, &loop.post);
2671 gfc_cleanup_loop (&loop);
2672 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
2673 as tree nodes in SS may not be valid in different scope. */
2676 tmp1 = gfc_finish_block (&body);
2677 /* If the WHERE construct is inside FORALL, fill the full temporary. */
2678 if (nested_forall_info != NULL)
2679 tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1, 1);
2681 gfc_add_expr_to_block (block, tmp1);
2683 *mask = tmp;
2684 *nmask = ntmp;
2686 return tmp1;
2690 /* Translate an assignment statement in a WHERE statement or construct
2691 statement. The MASK expression is used to control which elements
2692 of EXPR1 shall be assigned. */
2694 static tree
2695 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2, tree mask,
2696 tree count1, tree count2)
2698 gfc_se lse;
2699 gfc_se rse;
2700 gfc_ss *lss;
2701 gfc_ss *lss_section;
2702 gfc_ss *rss;
2704 gfc_loopinfo loop;
2705 tree tmp;
2706 stmtblock_t block;
2707 stmtblock_t body;
2708 tree index, maskexpr, tmp1;
2710 #if 0
2711 /* TODO: handle this special case.
2712 Special case a single function returning an array. */
2713 if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
2715 tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2716 if (tmp)
2717 return tmp;
2719 #endif
2721 /* Assignment of the form lhs = rhs. */
2722 gfc_start_block (&block);
2724 gfc_init_se (&lse, NULL);
2725 gfc_init_se (&rse, NULL);
2727 /* Walk the lhs. */
2728 lss = gfc_walk_expr (expr1);
2729 rss = NULL;
2731 /* In each where-assign-stmt, the mask-expr and the variable being
2732 defined shall be arrays of the same shape. */
2733 gcc_assert (lss != gfc_ss_terminator);
2735 /* The assignment needs scalarization. */
2736 lss_section = lss;
2738 /* Find a non-scalar SS from the lhs. */
2739 while (lss_section != gfc_ss_terminator
2740 && lss_section->type != GFC_SS_SECTION)
2741 lss_section = lss_section->next;
2743 gcc_assert (lss_section != gfc_ss_terminator);
2745 /* Initialize the scalarizer. */
2746 gfc_init_loopinfo (&loop);
2748 /* Walk the rhs. */
2749 rss = gfc_walk_expr (expr2);
2750 if (rss == gfc_ss_terminator)
2752 /* The rhs is scalar. Add a ss for the expression. */
2753 rss = gfc_get_ss ();
2754 rss->next = gfc_ss_terminator;
2755 rss->type = GFC_SS_SCALAR;
2756 rss->expr = expr2;
2759 /* Associate the SS with the loop. */
2760 gfc_add_ss_to_loop (&loop, lss);
2761 gfc_add_ss_to_loop (&loop, rss);
2763 /* Calculate the bounds of the scalarization. */
2764 gfc_conv_ss_startstride (&loop);
2766 /* Resolve any data dependencies in the statement. */
2767 gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2769 /* Setup the scalarizing loops. */
2770 gfc_conv_loop_setup (&loop);
2772 /* Setup the gfc_se structures. */
2773 gfc_copy_loopinfo_to_se (&lse, &loop);
2774 gfc_copy_loopinfo_to_se (&rse, &loop);
2776 rse.ss = rss;
2777 gfc_mark_ss_chain_used (rss, 1);
2778 if (loop.temp_ss == NULL)
2780 lse.ss = lss;
2781 gfc_mark_ss_chain_used (lss, 1);
2783 else
2785 lse.ss = loop.temp_ss;
2786 gfc_mark_ss_chain_used (lss, 3);
2787 gfc_mark_ss_chain_used (loop.temp_ss, 3);
2790 /* Start the scalarized loop body. */
2791 gfc_start_scalarized_body (&loop, &body);
2793 /* Translate the expression. */
2794 gfc_conv_expr (&rse, expr2);
2795 if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2797 gfc_conv_tmp_array_ref (&lse);
2798 gfc_advance_se_ss_chain (&lse);
2800 else
2801 gfc_conv_expr (&lse, expr1);
2803 /* Form the mask expression according to the mask tree list. */
2804 index = count1;
2805 tmp = mask;
2806 if (tmp != NULL)
2807 maskexpr = gfc_build_array_ref (tmp, index);
2808 else
2809 maskexpr = NULL;
2811 tmp = TREE_CHAIN (tmp);
2812 while (tmp)
2814 tmp1 = gfc_build_array_ref (tmp, index);
2815 maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1), maskexpr, tmp1);
2816 tmp = TREE_CHAIN (tmp);
2818 /* Use the scalar assignment as is. */
2819 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2820 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
2822 gfc_add_expr_to_block (&body, tmp);
2824 if (lss == gfc_ss_terminator)
2826 /* Increment count1. */
2827 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2828 count1, gfc_index_one_node);
2829 gfc_add_modify_expr (&body, count1, tmp);
2831 /* Use the scalar assignment as is. */
2832 gfc_add_block_to_block (&block, &body);
2834 else
2836 gcc_assert (lse.ss == gfc_ss_terminator
2837 && rse.ss == gfc_ss_terminator);
2839 if (loop.temp_ss != NULL)
2841 /* Increment count1 before finish the main body of a scalarized
2842 expression. */
2843 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2844 count1, gfc_index_one_node);
2845 gfc_add_modify_expr (&body, count1, tmp);
2846 gfc_trans_scalarized_loop_boundary (&loop, &body);
2848 /* We need to copy the temporary to the actual lhs. */
2849 gfc_init_se (&lse, NULL);
2850 gfc_init_se (&rse, NULL);
2851 gfc_copy_loopinfo_to_se (&lse, &loop);
2852 gfc_copy_loopinfo_to_se (&rse, &loop);
2854 rse.ss = loop.temp_ss;
2855 lse.ss = lss;
2857 gfc_conv_tmp_array_ref (&rse);
2858 gfc_advance_se_ss_chain (&rse);
2859 gfc_conv_expr (&lse, expr1);
2861 gcc_assert (lse.ss == gfc_ss_terminator
2862 && rse.ss == gfc_ss_terminator);
2864 /* Form the mask expression according to the mask tree list. */
2865 index = count2;
2866 tmp = mask;
2867 if (tmp != NULL)
2868 maskexpr = gfc_build_array_ref (tmp, index);
2869 else
2870 maskexpr = NULL;
2872 tmp = TREE_CHAIN (tmp);
2873 while (tmp)
2875 tmp1 = gfc_build_array_ref (tmp, index);
2876 maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
2877 maskexpr, tmp1);
2878 tmp = TREE_CHAIN (tmp);
2880 /* Use the scalar assignment as is. */
2881 tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2882 tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
2883 gfc_add_expr_to_block (&body, tmp);
2885 /* Increment count2. */
2886 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2887 count2, gfc_index_one_node);
2888 gfc_add_modify_expr (&body, count2, tmp);
2890 else
2892 /* Increment count1. */
2893 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2894 count1, gfc_index_one_node);
2895 gfc_add_modify_expr (&body, count1, tmp);
2898 /* Generate the copying loops. */
2899 gfc_trans_scalarizing_loops (&loop, &body);
2901 /* Wrap the whole thing up. */
2902 gfc_add_block_to_block (&block, &loop.pre);
2903 gfc_add_block_to_block (&block, &loop.post);
2904 gfc_cleanup_loop (&loop);
2907 return gfc_finish_block (&block);
2911 /* Translate the WHERE construct or statement.
2912 This function can be called iteratively to translate the nested WHERE
2913 construct or statement.
2914 MASK is the control mask, and PMASK is the pending control mask.
2915 TEMP records the temporary address which must be freed later. */
2917 static void
2918 gfc_trans_where_2 (gfc_code * code, tree mask, tree pmask,
2919 forall_info * nested_forall_info, stmtblock_t * block,
2920 temporary_list ** temp)
2922 gfc_expr *expr1;
2923 gfc_expr *expr2;
2924 gfc_code *cblock;
2925 gfc_code *cnext;
2926 tree tmp, tmp1, tmp2;
2927 tree count1, count2;
2928 tree mask_copy;
2929 int need_temp;
2931 /* the WHERE statement or the WHERE construct statement. */
2932 cblock = code->block;
2933 while (cblock)
2935 /* Has mask-expr. */
2936 if (cblock->expr)
2938 /* Ensure that the WHERE mask be evaluated only once. */
2939 tmp2 = gfc_evaluate_where_mask (cblock->expr, nested_forall_info,
2940 &tmp, &tmp1, temp, block);
2942 /* Set the control mask and the pending control mask. */
2943 /* It's a where-stmt. */
2944 if (mask == NULL)
2946 mask = tmp;
2947 pmask = tmp1;
2949 /* It's a nested where-stmt. */
2950 else if (mask && pmask == NULL)
2952 tree tmp2;
2953 /* Use the TREE_CHAIN to list the masks. */
2954 tmp2 = copy_list (mask);
2955 pmask = chainon (mask, tmp1);
2956 mask = chainon (tmp2, tmp);
2958 /* It's a masked-elsewhere-stmt. */
2959 else if (mask && cblock->expr)
2961 tree tmp2;
2962 tmp2 = copy_list (pmask);
2964 mask = pmask;
2965 tmp2 = chainon (tmp2, tmp);
2966 pmask = chainon (mask, tmp1);
2967 mask = tmp2;
2970 /* It's a elsewhere-stmt. No mask-expr is present. */
2971 else
2972 mask = pmask;
2974 /* Get the assignment statement of a WHERE statement, or the first
2975 statement in where-body-construct of a WHERE construct. */
2976 cnext = cblock->next;
2977 while (cnext)
2979 switch (cnext->op)
2981 /* WHERE assignment statement. */
2982 case EXEC_ASSIGN:
2983 expr1 = cnext->expr;
2984 expr2 = cnext->expr2;
2985 if (nested_forall_info != NULL)
2987 int nvar;
2988 gfc_expr **varexpr;
2990 nvar = nested_forall_info->nvar;
2991 varexpr = (gfc_expr **)
2992 gfc_getmem (nvar * sizeof (gfc_expr *));
2993 need_temp = gfc_check_dependency (expr1, expr2, varexpr,
2994 nvar);
2995 if (need_temp)
2996 gfc_trans_assign_need_temp (expr1, expr2, mask,
2997 nested_forall_info, block);
2998 else
3000 /* Variables to control maskexpr. */
3001 count1 = gfc_create_var (gfc_array_index_type, "count1");
3002 count2 = gfc_create_var (gfc_array_index_type, "count2");
3003 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
3004 gfc_add_modify_expr (block, count2, gfc_index_zero_node);
3006 tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3007 count2);
3009 tmp = gfc_trans_nested_forall_loop (nested_forall_info,
3010 tmp, 1, 1);
3011 gfc_add_expr_to_block (block, tmp);
3014 else
3016 /* Variables to control maskexpr. */
3017 count1 = gfc_create_var (gfc_array_index_type, "count1");
3018 count2 = gfc_create_var (gfc_array_index_type, "count2");
3019 gfc_add_modify_expr (block, count1, gfc_index_zero_node);
3020 gfc_add_modify_expr (block, count2, gfc_index_zero_node);
3022 tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3023 count2);
3024 gfc_add_expr_to_block (block, tmp);
3027 break;
3029 /* WHERE or WHERE construct is part of a where-body-construct. */
3030 case EXEC_WHERE:
3031 /* Ensure that MASK is not modified by next gfc_trans_where_2. */
3032 mask_copy = copy_list (mask);
3033 gfc_trans_where_2 (cnext, mask_copy, NULL, nested_forall_info,
3034 block, temp);
3035 break;
3037 default:
3038 gcc_unreachable ();
3041 /* The next statement within the same where-body-construct. */
3042 cnext = cnext->next;
3044 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
3045 cblock = cblock->block;
3050 /* As the WHERE or WHERE construct statement can be nested, we call
3051 gfc_trans_where_2 to do the translation, and pass the initial
3052 NULL values for both the control mask and the pending control mask. */
3054 tree
3055 gfc_trans_where (gfc_code * code)
3057 stmtblock_t block;
3058 temporary_list *temp, *p;
3059 tree args;
3060 tree tmp;
3062 gfc_start_block (&block);
3063 temp = NULL;
3065 gfc_trans_where_2 (code, NULL, NULL, NULL, &block, &temp);
3067 /* Add calls to free temporaries which were dynamically allocated. */
3068 while (temp)
3070 args = gfc_chainon_list (NULL_TREE, temp->temporary);
3071 tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
3072 gfc_add_expr_to_block (&block, tmp);
3074 p = temp;
3075 temp = temp->next;
3076 gfc_free (p);
3078 return gfc_finish_block (&block);
3082 /* CYCLE a DO loop. The label decl has already been created by
3083 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
3084 node at the head of the loop. We must mark the label as used. */
3086 tree
3087 gfc_trans_cycle (gfc_code * code)
3089 tree cycle_label;
3091 cycle_label = TREE_PURPOSE (code->ext.whichloop->backend_decl);
3092 TREE_USED (cycle_label) = 1;
3093 return build1_v (GOTO_EXPR, cycle_label);
3097 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
3098 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
3099 loop. */
3101 tree
3102 gfc_trans_exit (gfc_code * code)
3104 tree exit_label;
3106 exit_label = TREE_VALUE (code->ext.whichloop->backend_decl);
3107 TREE_USED (exit_label) = 1;
3108 return build1_v (GOTO_EXPR, exit_label);
3112 /* Translate the ALLOCATE statement. */
3114 tree
3115 gfc_trans_allocate (gfc_code * code)
3117 gfc_alloc *al;
3118 gfc_expr *expr;
3119 gfc_se se;
3120 tree tmp;
3121 tree parm;
3122 gfc_ref *ref;
3123 tree stat;
3124 tree pstat;
3125 tree error_label;
3126 stmtblock_t block;
3128 if (!code->ext.alloc_list)
3129 return NULL_TREE;
3131 gfc_start_block (&block);
3133 if (code->expr)
3135 tree gfc_int4_type_node = gfc_get_int_type (4);
3137 stat = gfc_create_var (gfc_int4_type_node, "stat");
3138 pstat = gfc_build_addr_expr (NULL, stat);
3140 error_label = gfc_build_label_decl (NULL_TREE);
3141 TREE_USED (error_label) = 1;
3143 else
3145 pstat = integer_zero_node;
3146 stat = error_label = NULL_TREE;
3150 for (al = code->ext.alloc_list; al != NULL; al = al->next)
3152 expr = al->expr;
3154 gfc_init_se (&se, NULL);
3155 gfc_start_block (&se.pre);
3157 se.want_pointer = 1;
3158 se.descriptor_only = 1;
3159 gfc_conv_expr (&se, expr);
3161 ref = expr->ref;
3163 /* Find the last reference in the chain. */
3164 while (ref && ref->next != NULL)
3166 gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3167 ref = ref->next;
3170 if (ref != NULL && ref->type == REF_ARRAY)
3172 /* An array. */
3173 gfc_array_allocate (&se, ref, pstat);
3175 else
3177 /* A scalar or derived type. */
3178 tree val;
3180 val = gfc_create_var (ppvoid_type_node, "ptr");
3181 tmp = gfc_build_addr_expr (ppvoid_type_node, se.expr);
3182 gfc_add_modify_expr (&se.pre, val, tmp);
3184 tmp = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
3185 parm = gfc_chainon_list (NULL_TREE, val);
3186 parm = gfc_chainon_list (parm, tmp);
3187 parm = gfc_chainon_list (parm, pstat);
3188 tmp = gfc_build_function_call (gfor_fndecl_allocate, parm);
3189 gfc_add_expr_to_block (&se.pre, tmp);
3191 if (code->expr)
3193 tmp = build1_v (GOTO_EXPR, error_label);
3194 parm =
3195 build2 (NE_EXPR, boolean_type_node, stat, integer_zero_node);
3196 tmp = build3_v (COND_EXPR, parm, tmp, build_empty_stmt ());
3197 gfc_add_expr_to_block (&se.pre, tmp);
3201 tmp = gfc_finish_block (&se.pre);
3202 gfc_add_expr_to_block (&block, tmp);
3205 /* Assign the value to the status variable. */
3206 if (code->expr)
3208 tmp = build1_v (LABEL_EXPR, error_label);
3209 gfc_add_expr_to_block (&block, tmp);
3211 gfc_init_se (&se, NULL);
3212 gfc_conv_expr_lhs (&se, code->expr);
3213 tmp = convert (TREE_TYPE (se.expr), stat);
3214 gfc_add_modify_expr (&block, se.expr, tmp);
3217 return gfc_finish_block (&block);
3221 /* Translate a DEALLOCATE statement.
3222 There are two cases within the for loop:
3223 (1) deallocate(a1, a2, a3) is translated into the following sequence
3224 _gfortran_deallocate(a1, 0B)
3225 _gfortran_deallocate(a2, 0B)
3226 _gfortran_deallocate(a3, 0B)
3227 where the STAT= variable is passed a NULL pointer.
3228 (2) deallocate(a1, a2, a3, stat=i) is translated into the following
3229 astat = 0
3230 _gfortran_deallocate(a1, &stat)
3231 astat = astat + stat
3232 _gfortran_deallocate(a2, &stat)
3233 astat = astat + stat
3234 _gfortran_deallocate(a3, &stat)
3235 astat = astat + stat
3236 In case (1), we simply return at the end of the for loop. In case (2)
3237 we set STAT= astat. */
3238 tree
3239 gfc_trans_deallocate (gfc_code * code)
3241 gfc_se se;
3242 gfc_alloc *al;
3243 gfc_expr *expr;
3244 tree apstat, astat, parm, pstat, stat, tmp, type, var;
3245 stmtblock_t block;
3247 gfc_start_block (&block);
3249 /* Set up the optional STAT= */
3250 if (code->expr)
3252 tree gfc_int4_type_node = gfc_get_int_type (4);
3254 /* Variable used with the library call. */
3255 stat = gfc_create_var (gfc_int4_type_node, "stat");
3256 pstat = gfc_build_addr_expr (NULL, stat);
3258 /* Running total of possible deallocation failures. */
3259 astat = gfc_create_var (gfc_int4_type_node, "astat");
3260 apstat = gfc_build_addr_expr (NULL, astat);
3262 /* Initialize astat to 0. */
3263 gfc_add_modify_expr (&block, astat, build_int_cst (TREE_TYPE (astat), 0));
3265 else
3267 pstat = apstat = null_pointer_node;
3268 stat = astat = NULL_TREE;
3271 for (al = code->ext.alloc_list; al != NULL; al = al->next)
3273 expr = al->expr;
3274 gcc_assert (expr->expr_type == EXPR_VARIABLE);
3276 gfc_init_se (&se, NULL);
3277 gfc_start_block (&se.pre);
3279 se.want_pointer = 1;
3280 se.descriptor_only = 1;
3281 gfc_conv_expr (&se, expr);
3283 if (expr->rank)
3284 tmp = gfc_array_deallocate (se.expr, pstat);
3285 else
3287 type = build_pointer_type (TREE_TYPE (se.expr));
3288 var = gfc_create_var (type, "ptr");
3289 tmp = gfc_build_addr_expr (type, se.expr);
3290 gfc_add_modify_expr (&se.pre, var, tmp);
3292 parm = gfc_chainon_list (NULL_TREE, var);
3293 parm = gfc_chainon_list (parm, pstat);
3294 tmp = gfc_build_function_call (gfor_fndecl_deallocate, parm);
3297 gfc_add_expr_to_block (&se.pre, tmp);
3299 /* Keep track of the number of failed deallocations by adding stat
3300 of the last deallocation to the running total. */
3301 if (code->expr)
3303 apstat = build2 (PLUS_EXPR, TREE_TYPE (stat), astat, stat);
3304 gfc_add_modify_expr (&se.pre, astat, apstat);
3307 tmp = gfc_finish_block (&se.pre);
3308 gfc_add_expr_to_block (&block, tmp);
3312 /* Assign the value to the status variable. */
3313 if (code->expr)
3315 gfc_init_se (&se, NULL);
3316 gfc_conv_expr_lhs (&se, code->expr);
3317 tmp = convert (TREE_TYPE (se.expr), astat);
3318 gfc_add_modify_expr (&block, se.expr, tmp);
3321 return gfc_finish_block (&block);