OSDN Git Service

1b56cf478de03c6d09925eacc906786ec20bdca5
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-stmt.c
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>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
22
23
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"
39
40 typedef struct iter_info
41 {
42   tree var;
43   tree start;
44   tree end;
45   tree step;
46   struct iter_info *next;
47 }
48 iter_info;
49
50 typedef  struct temporary_list
51 {
52   tree temporary;
53   struct temporary_list *next;
54 }
55 temporary_list;
56
57 typedef struct forall_info
58 {
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;
67 }
68 forall_info;
69
70 static void gfc_trans_where_2 (gfc_code *, tree, tree, forall_info *,
71                                stmtblock_t *, temporary_list **temp);
72
73 /* Translate a F95 label number to a LABEL_EXPR.  */
74
75 tree
76 gfc_trans_label_here (gfc_code * code)
77 {
78   return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
79 }
80
81
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.  */
85
86 void
87 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
88 {
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);
97 }
98
99 /* Translate a label assignment statement.  */
100
101 tree
102 gfc_trans_label_assign (gfc_code * code)
103 {
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;
111
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);
116
117   len = GFC_DECL_STRING_LEN (se.expr);
118   addr = GFC_DECL_ASSIGN_ADDR (se.expr);
119
120   label_tree = gfc_get_label_decl (code->label);
121
122   if (code->label->defined == ST_LABEL_TARGET)
123     {
124       label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
125       len_tree = integer_minus_one_node;
126     }
127   else
128     {
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);
134     }
135
136   gfc_add_modify_expr (&se.pre, len, len_tree);
137   gfc_add_modify_expr (&se.pre, addr, label_tree);
138
139   return gfc_finish_block (&se.pre);
140 }
141
142 /* Translate a GOTO statement.  */
143
144 tree
145 gfc_trans_goto (gfc_code * code)
146 {
147   tree assigned_goto;
148   tree target;
149   tree tmp;
150   tree assign_error;
151   tree range_error;
152   gfc_se se;
153
154
155   if (code->label != NULL)
156     return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
157
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);
167
168   assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
169
170   code = code->block;
171   if (code == NULL)
172     {
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);
176     }
177
178   /* Check the label list.  */
179   range_error = gfc_build_cstring_const ("Assigned label is not in the list");
180
181   do
182     {
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;
191     }
192   while (code != NULL);
193   gfc_trans_runtime_check (boolean_true_node, range_error, &se.pre);
194   return gfc_finish_block (&se.pre); 
195 }
196
197
198 /* Translate an ENTRY statement.  Just adds a label for this entry point.  */
199 tree
200 gfc_trans_entry (gfc_code * code)
201 {
202   return build1_v (LABEL_EXPR, code->ext.entry->label);
203 }
204
205
206 /* Translate the CALL statement.  Builds a call to an F95 subroutine.  */
207
208 tree
209 gfc_trans_call (gfc_code * code)
210 {
211   gfc_se se;
212   int has_alternate_specifier;
213
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);
218
219   gcc_assert (code->resolved_sym);
220
221   /* Translate the call.  */
222   has_alternate_specifier
223     = gfc_conv_function_call (&se, code->resolved_sym, code->ext.actual);
224
225   /* A subroutine without side-effect, by definition, does nothing!  */
226   TREE_SIDE_EFFECTS (se.expr) = 1;
227
228   /* Chain the pieces together and return the block.  */
229   if (has_alternate_specifier)
230     {
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);
238     }
239   else
240     gfc_add_expr_to_block (&se.pre, se.expr);
241
242   gfc_add_block_to_block (&se.pre, &se.post);
243   return gfc_finish_block (&se.pre);
244 }
245
246
247 /* Translate the RETURN statement.  */
248
249 tree
250 gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
251 {
252   if (code->expr)
253     {
254       gfc_se se;
255       tree tmp;
256       tree result;
257
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.  */
261
262       result = gfc_get_fake_result_decl (NULL);
263       if (!result)
264         {
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 ());
268         }
269
270       /* Start a new block for this statement.  */
271       gfc_init_se (&se, NULL);
272       gfc_start_block (&se.pre);
273
274       gfc_conv_expr (&se, code->expr);
275
276       tmp = build2 (MODIFY_EXPR, TREE_TYPE (result), result, se.expr);
277       gfc_add_expr_to_block (&se.pre, tmp);
278
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);
283     }
284   else
285     return build1_v (GOTO_EXPR, gfc_get_return_label ());
286 }
287
288
289 /* Translate the PAUSE statement.  We have to translate this statement
290    to a runtime library call.  */
291
292 tree
293 gfc_trans_pause (gfc_code * code)
294 {
295   tree gfc_int4_type_node = gfc_get_int_type (4);
296   gfc_se se;
297   tree args;
298   tree tmp;
299   tree fndecl;
300
301   /* Start a new block for this statement.  */
302   gfc_init_se (&se, NULL);
303   gfc_start_block (&se.pre);
304
305
306   if (code->expr == NULL)
307     {
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;
311     }
312   else
313     {
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;
318     }
319
320   tmp = build_function_call_expr (fndecl, args);
321   gfc_add_expr_to_block (&se.pre, tmp);
322
323   gfc_add_block_to_block (&se.pre, &se.post);
324
325   return gfc_finish_block (&se.pre);
326 }
327
328
329 /* Translate the STOP statement.  We have to translate this statement
330    to a runtime library call.  */
331
332 tree
333 gfc_trans_stop (gfc_code * code)
334 {
335   tree gfc_int4_type_node = gfc_get_int_type (4);
336   gfc_se se;
337   tree args;
338   tree tmp;
339   tree fndecl;
340
341   /* Start a new block for this statement.  */
342   gfc_init_se (&se, NULL);
343   gfc_start_block (&se.pre);
344
345
346   if (code->expr == NULL)
347     {
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;
351     }
352   else
353     {
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;
358     }
359
360   tmp = build_function_call_expr (fndecl, args);
361   gfc_add_expr_to_block (&se.pre, tmp);
362
363   gfc_add_block_to_block (&se.pre, &se.post);
364
365   return gfc_finish_block (&se.pre);
366 }
367
368
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.
372
373    We translate:
374
375         IF (cond) THEN
376            then_clause
377         ELSEIF (cond2)
378            elseif_clause
379         ELSE
380            else_clause
381         ENDIF
382
383    into:
384
385         pre_cond_s;
386         if (cond_s)
387           {
388             then_clause;
389           }
390         else
391           {
392             pre_cond_s
393             if (cond_s)
394               {
395                 elseif_clause
396               }
397             else
398               {
399                 else_clause;
400               }
401           }
402
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.  */
408
409 static tree
410 gfc_trans_if_1 (gfc_code * code)
411 {
412   gfc_se if_se;
413   tree stmt, elsestmt;
414
415   /* Check for an unconditional ELSE clause.  */
416   if (!code->expr)
417     return gfc_trans_code (code->next);
418
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);
422
423   /* Calculate the IF condition expression.  */
424   gfc_conv_expr_val (&if_se, code->expr);
425
426   /* Translate the THEN clause.  */
427   stmt = gfc_trans_code (code->next);
428
429   /* Translate the ELSE clause.  */
430   if (code->block)
431     elsestmt = gfc_trans_if_1 (code->block);
432   else
433     elsestmt = build_empty_stmt ();
434
435   /* Build the condition expression and add it to the condition block.  */
436   stmt = build3_v (COND_EXPR, if_se.expr, stmt, elsestmt);
437   
438   gfc_add_expr_to_block (&if_se.pre, stmt);
439
440   /* Finish off this statement.  */
441   return gfc_finish_block (&if_se.pre);
442 }
443
444 tree
445 gfc_trans_if (gfc_code * code)
446 {
447   /* Ignore the top EXEC_IF, it only announces an IF construct. The
448      actual code we must translate is in code->block.  */
449
450   return gfc_trans_if_1 (code->block);
451 }
452
453
454 /* Translage an arithmetic IF expression.
455
456    IF (cond) label1, label2, label3 translates to
457
458     if (cond <= 0)
459       {
460         if (cond < 0)
461           goto label1;
462         else // cond == 0
463           goto label2;
464       }
465     else // cond > 0
466       goto label3;
467
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
470
471     if (cond <= 0)
472       goto label1;
473     else
474       goto label3;
475 */
476
477 tree
478 gfc_trans_arithmetic_if (gfc_code * code)
479 {
480   gfc_se se;
481   tree tmp;
482   tree branch1;
483   tree branch2;
484   tree zero;
485
486   /* Start a new block.  */
487   gfc_init_se (&se, NULL);
488   gfc_start_block (&se.pre);
489
490   /* Pre-evaluate COND.  */
491   gfc_conv_expr_val (&se, code->expr);
492
493   /* Build something to compare with.  */
494   zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
495
496   if (code->label->value != code->label2->value)
497     {
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));
502
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);
507
508       branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
509     }
510   else
511     branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
512
513   if (code->label->value != code->label3->value
514       && code->label2->value != code->label3->value)
515     {
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);
520     }
521
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);
525 }
526
527
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:
533
534    DO dovar = from, to, step
535       body
536    END DO
537
538    to:
539
540    [Evaluate loop bounds and step]
541    dovar = from;
542    if ((step > 0) ? (dovar <= to) : (dovar => to))
543     {
544       for (;;)
545         {
546           body;
547    cycle_label:
548           cond = (dovar == to);
549           dovar += step;
550           if (cond) goto end_label;
551         }
552       }
553    end_label:
554
555    This helps the optimizers by avoiding the extra induction variable
556    used in the general case.  */
557
558 static tree
559 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
560                      tree from, tree to, tree step)
561 {
562   stmtblock_t body;
563   tree type;
564   tree cond;
565   tree tmp;
566   tree cycle_label;
567   tree exit_label;
568   
569   type = TREE_TYPE (dovar);
570
571   /* Initialize the DO variable: dovar = from.  */
572   gfc_add_modify_expr (pblock, dovar, from);
573
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);
577
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);
580
581   /* Loop body.  */
582   gfc_start_block (&body);
583
584   /* Main loop body.  */
585   tmp = gfc_trans_code (code->block->next);
586   gfc_add_expr_to_block (&body, tmp);
587
588   /* Label for cycle statements (if needed).  */
589   if (TREE_USED (cycle_label))
590     {
591       tmp = build1_v (LABEL_EXPR, cycle_label);
592       gfc_add_expr_to_block (&body, tmp);
593     }
594
595   /* Evaluate the loop condition.  */
596   cond = build2 (EQ_EXPR, boolean_type_node, dovar, to);
597   cond = gfc_evaluate_now (cond, &body);
598
599   /* Increment the loop variable.  */
600   tmp = build2 (PLUS_EXPR, type, dovar, step);
601   gfc_add_modify_expr (&body, dovar, tmp);
602
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);
608
609   /* Finish the loop body.  */
610   tmp = gfc_finish_block (&body);
611   tmp = build1_v (LOOP_EXPR, tmp);
612
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);
620
621   /* Add the exit label.  */
622   tmp = build1_v (LABEL_EXPR, exit_label);
623   gfc_add_expr_to_block (pblock, tmp);
624
625   return gfc_finish_block (pblock);
626 }
627
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.
631
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.
635
636    We translate a do loop from:
637
638    DO dovar = from, to, step
639       body
640    END DO
641
642    to:
643
644    [evaluate loop bounds and step]
645    count = to + step - from;
646    dovar = from;
647    for (;;)
648      {
649        body;
650 cycle_label:
651        dovar += step
652        count--;
653        if (count <=0) goto exit_label;
654      }
655 exit_label:
656
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.  */
661
662 tree
663 gfc_trans_do (gfc_code * code)
664 {
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;
679
680   gfc_start_block (&block);
681
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);
688
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);
693
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);
698
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);
703
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);
709       
710   /* Initialize loop count. This code is executed before we enter the
711      loop body. We generate: count = (to + step - from) / step.  */
712
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)
716     {
717       tmp = fold_build2 (TRUNC_DIV_EXPR, type, tmp, step);
718       count = gfc_create_var (type, "count");
719     }
720   else
721     {
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");
728     }
729   gfc_add_modify_expr (&block, count, tmp);
730
731   count_one = convert (TREE_TYPE (count), integer_one_node);
732
733   /* Initialize the DO variable: dovar = from.  */
734   gfc_add_modify_expr (&block, dovar, from);
735
736   /* Loop body.  */
737   gfc_start_block (&body);
738
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);
742
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);
750
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).  */
755
756   code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
757
758   /* Main loop body.  */
759   tmp = gfc_trans_code (code->block->next);
760   gfc_add_expr_to_block (&body, tmp);
761
762   /* Label for cycle statements (if needed).  */
763   if (TREE_USED (cycle_label))
764     {
765       tmp = build1_v (LABEL_EXPR, cycle_label);
766       gfc_add_expr_to_block (&body, tmp);
767     }
768
769   /* Increment the loop variable.  */
770   tmp = build2 (PLUS_EXPR, type, dovar, step);
771   gfc_add_modify_expr (&body, dovar, tmp);
772
773   /* Decrement the loop count.  */
774   tmp = build2 (MINUS_EXPR, TREE_TYPE (count), count, count_one);
775   gfc_add_modify_expr (&body, count, tmp);
776
777   /* End of loop body.  */
778   tmp = gfc_finish_block (&body);
779
780   /* The for loop itself.  */
781   tmp = build1_v (LOOP_EXPR, tmp);
782   gfc_add_expr_to_block (&block, tmp);
783
784   /* Add the exit label.  */
785   tmp = build1_v (LABEL_EXPR, exit_label);
786   gfc_add_expr_to_block (&block, tmp);
787
788   return gfc_finish_block (&block);
789 }
790
791
792 /* Translate the DO WHILE construct.
793
794    We translate
795
796    DO WHILE (cond)
797       body
798    END DO
799
800    to:
801
802    for ( ; ; )
803      {
804        pre_cond;
805        if (! cond) goto exit_label;
806        body;
807 cycle_label:
808      }
809 exit_label:
810
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.  */
814
815 tree
816 gfc_trans_do_while (gfc_code * code)
817 {
818   gfc_se cond;
819   tree tmp;
820   tree cycle_label;
821   tree exit_label;
822   stmtblock_t block;
823
824   /* Everything we build here is part of the loop body.  */
825   gfc_start_block (&block);
826
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);
830
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);
833
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);
839
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);
845
846   /* The main body of the loop.  */
847   tmp = gfc_trans_code (code->block->next);
848   gfc_add_expr_to_block (&block, tmp);
849
850   /* Label for cycle statements (if needed).  */
851   if (TREE_USED (cycle_label))
852     {
853       tmp = build1_v (LABEL_EXPR, cycle_label);
854       gfc_add_expr_to_block (&block, tmp);
855     }
856
857   /* End of loop body.  */
858   tmp = gfc_finish_block (&block);
859
860   gfc_init_block (&block);
861   /* Build the loop.  */
862   tmp = build1_v (LOOP_EXPR, tmp);
863   gfc_add_expr_to_block (&block, tmp);
864
865   /* Add the exit label.  */
866   tmp = build1_v (LABEL_EXPR, exit_label);
867   gfc_add_expr_to_block (&block, tmp);
868
869   return gfc_finish_block (&block);
870 }
871
872
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.
878
879    For example, we translate this,
880
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
891
892    to the GENERIC equivalent,
893
894      switch (expr)
895        {
896          case (minimum value for typeof(expr) ... 100:
897          case 101:
898          case 105 ... 114:
899            block1:
900            goto end_label;
901
902          case 200 ... (maximum value for typeof(expr):
903          case 190 ... 199:
904            block2;
905            goto end_label;
906
907          case 300:
908            block_3;
909            goto end_label;
910
911          default:
912            block_4;
913            goto end_label;
914        }
915
916      end_label:  */
917
918 static tree
919 gfc_trans_integer_select (gfc_code * code)
920 {
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;
928
929   gfc_start_block (&block);
930
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);
935
936   end_label = gfc_build_label_decl (NULL_TREE);
937
938   gfc_init_block (&body);
939
940   for (c = code->block; c; c = c->block)
941     {
942       for (cp = c->ext.case_list; cp; cp = cp->next)
943         {
944           tree low, high;
945           tree label;
946
947           /* Assume it's the default case.  */
948           low = high = NULL_TREE;
949
950           if (cp->low)
951             {
952               low = gfc_conv_constant_to_tree (cp->low);
953
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));
958             }
959
960           if (cp->high)
961             {
962               /* Three cases are possible here:
963
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).
971
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.  */
977
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);
983
984               /* Unbounded case.  */
985               if (!cp->low)
986                 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
987             }
988
989           /* Build a label.  */
990           label = gfc_build_label_decl (NULL_TREE);
991
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);
996         }
997
998       /* Add the statements for this case.  */
999       tmp = gfc_trans_code (c->next);
1000       gfc_add_expr_to_block (&body, tmp);
1001
1002       /* Break to the end of the construct.  */
1003       tmp = build1_v (GOTO_EXPR, end_label);
1004       gfc_add_expr_to_block (&body, tmp);
1005     }
1006
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);
1010
1011   tmp = build1_v (LABEL_EXPR, end_label);
1012   gfc_add_expr_to_block (&block, tmp);
1013
1014   return gfc_finish_block (&block);
1015 }
1016
1017
1018 /* Translate the SELECT CASE construct for LOGICAL case expressions.
1019
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.
1023
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
1027
1028    if {} else {};
1029
1030    expression in GENERIC.  */
1031
1032 static tree
1033 gfc_trans_logical_select (gfc_code * code)
1034 {
1035   gfc_code *c;
1036   gfc_code *t, *f, *d;
1037   gfc_case *cp;
1038   gfc_se se;
1039   stmtblock_t block;
1040
1041   /* Assume we don't have any cases at all.  */
1042   t = f = d = NULL;
1043
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)
1050     {
1051       for (cp = c->ext.case_list; cp; cp = cp->next)
1052         {
1053           if (cp->low)
1054             {
1055               if (cp->low->value.logical == 0) /* .FALSE.  */
1056                 f = c;
1057               else /* if (cp->value.logical != 0), thus .TRUE.  */
1058                 t = c;
1059             }
1060           else
1061             d = c;
1062         }
1063     }
1064
1065   /* Start a new block.  */
1066   gfc_start_block (&block);
1067
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);
1073
1074   if (t == f && t != NULL)
1075     {
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));
1080     }
1081   else
1082     {
1083       tree true_tree, false_tree;
1084
1085       true_tree = build_empty_stmt ();
1086       false_tree = build_empty_stmt ();
1087
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)
1094         {
1095           if (t == NULL)
1096             t = d;
1097           else
1098             f = d;
1099         }
1100
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);
1105
1106       if (f != NULL)
1107         false_tree = gfc_trans_code (f->next);
1108
1109       gfc_add_expr_to_block (&block, build3_v (COND_EXPR, se.expr,
1110                                                true_tree, false_tree));
1111     }
1112
1113   return gfc_finish_block (&block);
1114 }
1115
1116
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.  */
1125
1126 static tree
1127 gfc_trans_character_select (gfc_code *code)
1128 {
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;
1135
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;
1140
1141   if (select_struct == NULL)
1142     {
1143       tree gfc_int4_type_node = gfc_get_int_type (4);
1144
1145       select_struct = make_node (RECORD_TYPE);
1146       TYPE_NAME (select_struct) = get_identifier ("_jump_struct");
1147
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)
1153
1154       ADD_FIELD (string1, pchar_type_node);
1155       ADD_FIELD (string1_len, gfc_int4_type_node);
1156
1157       ADD_FIELD (string2, pchar_type_node);
1158       ADD_FIELD (string2_len, gfc_int4_type_node);
1159
1160       ADD_FIELD (target, pvoid_type_node);
1161 #undef ADD_FIELD
1162
1163       gfc_finish_type (select_struct);
1164     }
1165
1166   cp = code->block->ext.case_list;
1167   while (cp->left != NULL)
1168     cp = cp->left;
1169
1170   n = 0;
1171   for (d = cp; d; d = d->right)
1172     d->n = n++;
1173
1174   if (n != 0)
1175     labels = gfc_getmem (n * sizeof (tree));
1176   else
1177     labels = NULL;
1178
1179   for(i = 0; i < n; i++)
1180     {
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;
1186     }
1187
1188   end_label = gfc_build_label_decl (NULL_TREE);
1189
1190   /* Generate the body */
1191   gfc_start_block (&block);
1192   gfc_init_block (&body);
1193
1194   for (c = code->block; c; c = c->block)
1195     {
1196       for (d = c->ext.case_list; d; d = d->next)
1197         {
1198           tmp = build1_v (LABEL_EXPR, labels[d->n]);
1199           gfc_add_expr_to_block (&body, tmp);
1200         }
1201
1202       tmp = gfc_trans_code (c->next);
1203       gfc_add_expr_to_block (&body, tmp);
1204
1205       tmp = build1_v (GOTO_EXPR, end_label);
1206       gfc_add_expr_to_block (&body, tmp);
1207     }
1208
1209   /* Generate the structure describing the branches */
1210   init = NULL_TREE;
1211   i = 0;
1212
1213   for(d = cp; d; d = d->right, i++)
1214     {
1215       node = NULL_TREE;
1216
1217       gfc_init_se (&se, NULL);
1218
1219       if (d->low == NULL)
1220         {
1221           node = tree_cons (ss_string1, null_pointer_node, node);
1222           node = tree_cons (ss_string1_len, integer_zero_node, node);
1223         }
1224       else
1225         {
1226           gfc_conv_expr_reference (&se, d->low);
1227
1228           node = tree_cons (ss_string1, se.expr, node);
1229           node = tree_cons (ss_string1_len, se.string_length, node);
1230         }
1231
1232       if (d->high == NULL)
1233         {
1234           node = tree_cons (ss_string2, null_pointer_node, node);
1235           node = tree_cons (ss_string2_len, integer_zero_node, node);
1236         }
1237       else
1238         {
1239           gfc_init_se (&se, NULL);
1240           gfc_conv_expr_reference (&se, d->high);
1241
1242           node = tree_cons (ss_string2, se.expr, node);
1243           node = tree_cons (ss_string2_len, se.string_length, node);
1244         }
1245
1246       tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
1247       node = tree_cons (ss_target, tmp, node);
1248
1249       tmp = build_constructor_from_list (select_struct, nreverse (node));
1250       init = tree_cons (NULL_TREE, tmp, init);
1251     }
1252
1253   type = build_array_type (select_struct, build_index_type
1254                            (build_int_cst (NULL_TREE, n - 1)));
1255
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;
1267
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);
1271
1272   tmp = build_int_cst (NULL_TREE, n);
1273   args = gfc_chainon_list (args, tmp);
1274
1275   tmp = gfc_build_addr_expr (pvoid_type_node, end_label);
1276   args = gfc_chainon_list (args, tmp);
1277
1278   gfc_init_se (&se, NULL);
1279   gfc_conv_expr_reference (&se, code->expr);
1280
1281   args = gfc_chainon_list (args, se.expr);
1282   args = gfc_chainon_list (args, se.string_length);
1283
1284   gfc_add_block_to_block (&block, &se.pre);
1285
1286   tmp = build_function_call_expr (gfor_fndecl_select_string, args);
1287   tmp = build1 (GOTO_EXPR, void_type_node, tmp);
1288   gfc_add_expr_to_block (&block, tmp);
1289
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);
1294
1295   if (n != 0)
1296     gfc_free (labels);
1297
1298   return gfc_finish_block (&block);
1299 }
1300
1301
1302 /* Translate the three variants of the SELECT CASE construct.
1303
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.
1307
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.
1311
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.  */
1315
1316 tree
1317 gfc_trans_select (gfc_code * code)
1318 {
1319   gcc_assert (code && code->expr);
1320
1321   /* Empty SELECT constructs are legal.  */
1322   if (code->block == NULL)
1323     return build_empty_stmt ();
1324
1325   /* Select the correct translation function.  */
1326   switch (code->expr->ts.type)
1327     {
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 */
1334     }
1335 }
1336
1337
1338 /* Generate the loops for a FORALL block.  The normal loop format:
1339     count = (end - start + step) / step
1340     loopvar = start
1341     while (1)
1342       {
1343         if (count <=0 )
1344           goto end_of_loop
1345         <body>
1346         loopvar += step
1347         count --
1348       }
1349     end_of_loop:  */
1350
1351 static tree
1352 gfc_trans_forall_loop (forall_info *forall_tmp, int nvar, tree body, int mask_flag)
1353 {
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;
1362
1363   iter = forall_tmp->this_loop;
1364   for (n = 0; n < nvar; n++)
1365     {
1366       var = iter->var;
1367       start = iter->start;
1368       end = iter->end;
1369       step = iter->step;
1370
1371       exit_label = gfc_build_label_decl (NULL_TREE);
1372       TREE_USED (exit_label) = 1;
1373
1374       /* The loop counter.  */
1375       count = gfc_create_var (TREE_TYPE (var), "count");
1376
1377       /* The body of the loop.  */
1378       gfc_init_block (&block);
1379
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);
1385
1386       /* The main loop body.  */
1387       gfc_add_expr_to_block (&block, body);
1388
1389       /* Increment the loop variable.  */
1390       tmp = build2 (PLUS_EXPR, TREE_TYPE (var), var, step);
1391       gfc_add_modify_expr (&block, var, tmp);
1392
1393       /* Advance to the next mask element.  Only do this for the
1394          innermost loop.  */
1395       if (n == 0 && mask_flag && forall_tmp->mask)
1396         {
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);
1401         }
1402
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);
1406
1407       body = gfc_finish_block (&block);
1408
1409       /* Loop var initialization.  */
1410       gfc_init_block (&block);
1411       gfc_add_modify_expr (&block, var, start);
1412
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);
1418
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);
1424
1425       /* The loop expression.  */
1426       tmp = build1_v (LOOP_EXPR, body);
1427       gfc_add_expr_to_block (&block, tmp);
1428
1429       /* The exit label.  */
1430       tmp = build1_v (LABEL_EXPR, exit_label);
1431       gfc_add_expr_to_block (&block, tmp);
1432
1433       body = gfc_finish_block (&block);
1434       iter = iter->next;
1435     }
1436   return body;
1437 }
1438
1439
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.  */
1445
1446 static tree
1447 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
1448                               int mask_flag, int nest_flag)
1449 {
1450   tree tmp;
1451   int nvar;
1452   forall_info *forall_tmp;
1453   tree pmask, mask, maskindex;
1454
1455   forall_tmp = nested_forall_info;
1456   /* Generate loops for nested forall.  */
1457   if (nest_flag)
1458     {
1459       while (forall_tmp->next_nest != NULL)
1460         forall_tmp = forall_tmp->next_nest;
1461       while (forall_tmp != NULL)
1462         {
1463           /* Generate body with masks' control.  */
1464           if (mask_flag)
1465             {
1466               pmask = forall_tmp->pmask;
1467               mask = forall_tmp->mask;
1468               maskindex = forall_tmp->maskindex;
1469
1470               if (mask)
1471                 {
1472                   /* If a mask was specified make the assignment conditional.  */
1473                   if (pmask)
1474                     tmp = build_fold_indirect_ref (mask);
1475                   else
1476                     tmp = mask;
1477                   tmp = gfc_build_array_ref (tmp, maskindex);
1478
1479                   body = build3_v (COND_EXPR, tmp, body, build_empty_stmt ());
1480                 }
1481             }
1482           nvar = forall_tmp->nvar;
1483           body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1484           forall_tmp = forall_tmp->outer;
1485         }
1486     }
1487   else
1488     {
1489       nvar = forall_tmp->nvar;
1490       body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1491     }
1492
1493   return body;
1494 }
1495
1496
1497 /* Allocate data for holding a temporary array.  Returns either a local
1498    temporary array or a pointer variable.  */
1499
1500 static tree
1501 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
1502                  tree elem_type)
1503 {
1504   tree tmpvar;
1505   tree type;
1506   tree tmp;
1507   tree args;
1508
1509   if (INTEGER_CST_P (size))
1510     {
1511       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, size,
1512                          gfc_index_one_node);
1513     }
1514   else
1515     tmp = NULL_TREE;
1516
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))
1520     {
1521       gcc_assert (INTEGER_CST_P (size));
1522       tmpvar = gfc_create_var (type, "temp");
1523       *pdata = NULL_TREE;
1524     }
1525   else
1526     {
1527       tmpvar = gfc_create_var (build_pointer_type (type), "temp");
1528       *pdata = convert (pvoid_type_node, tmpvar);
1529
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 = build_function_call_expr (tmp, args);
1538       tmp = convert (TREE_TYPE (tmpvar), tmp);
1539       gfc_add_modify_expr (pblock, tmpvar, tmp);
1540     }
1541   return tmpvar;
1542 }
1543
1544
1545 /* Generate codes to copy the temporary to the actual lhs.  */
1546
1547 static tree
1548 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree count3,
1549                                tree count1, tree wheremask)
1550 {
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;
1557
1558   /* Walk the lhs.  */
1559   lss = gfc_walk_expr (expr);
1560
1561   if (lss == gfc_ss_terminator)
1562     {
1563       gfc_start_block (&block);
1564
1565       gfc_init_se (&lse, NULL);
1566
1567       /* Translate the expression.  */
1568       gfc_conv_expr (&lse, expr);
1569
1570       /* Form the expression for the temporary.  */
1571       tmp = gfc_build_array_ref (tmp1, count1);
1572
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);
1577
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);
1582
1583       tmp = gfc_finish_block (&block);
1584     }
1585   else
1586     {
1587       gfc_start_block (&block);
1588
1589       gfc_init_loopinfo (&loop1);
1590       gfc_init_se (&rse, NULL);
1591       gfc_init_se (&lse, NULL);
1592
1593       /* Associate the lss with the loop.  */
1594       gfc_add_ss_to_loop (&loop1, lss);
1595
1596       /* Calculate the bounds of the scalarization.  */
1597       gfc_conv_ss_startstride (&loop1);
1598       /* Setup the scalarizing loops.  */
1599       gfc_conv_loop_setup (&loop1);
1600
1601       gfc_mark_ss_chain_used (lss, 1);
1602
1603       /* Start the scalarized loop body.  */
1604       gfc_start_scalarized_body (&loop1, &body);
1605
1606       /* Setup the gfc_se structures.  */
1607       gfc_copy_loopinfo_to_se (&lse, &loop1);
1608       lse.ss = lss;
1609
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);
1615
1616       /* Use the scalar assignment.  */
1617       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
1618
1619      /* Form the mask expression according to the mask tree list.  */
1620      if (wheremask)
1621        {
1622          wheremaskexpr = gfc_build_array_ref (wheremask, count3);
1623          tmp2 = TREE_CHAIN (wheremask);
1624          while (tmp2)
1625            {
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);
1630            }
1631          tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1632        }
1633
1634       gfc_add_expr_to_block (&body, tmp);
1635
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);
1640
1641       /* Increment count3.  */
1642       if (count3)
1643         {
1644           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1645                              count3, gfc_index_one_node);
1646           gfc_add_modify_expr (&body, count3, tmp);
1647         }
1648
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);
1654
1655       tmp = gfc_finish_block (&block);
1656     }
1657   return tmp;
1658 }
1659
1660
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.  */
1664
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)
1669 {
1670   stmtblock_t block, body1;
1671   gfc_loopinfo loop;
1672   gfc_se lse;
1673   gfc_se rse;
1674   tree tmp, tmp2;
1675   tree wheremaskexpr;
1676
1677   gfc_start_block (&block);
1678
1679   gfc_init_se (&rse, NULL);
1680   gfc_init_se (&lse, NULL);
1681
1682   if (lss == gfc_ss_terminator)
1683     {
1684       gfc_init_block (&body1);
1685       gfc_conv_expr (&rse, expr2);
1686       lse.expr = gfc_build_array_ref (tmp1, count1);
1687     }
1688   else
1689     {
1690       /* Initialize the loop.  */
1691       gfc_init_loopinfo (&loop);
1692
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);
1696
1697       gfc_conv_ss_startstride (&loop);
1698       gfc_conv_loop_setup (&loop);
1699
1700       gfc_mark_ss_chain_used (rss, 1);
1701       /* Start the loop body.  */
1702       gfc_start_scalarized_body (&loop, &body1);
1703
1704       /* Translate the expression.  */
1705       gfc_copy_loopinfo_to_se (&rse, &loop);
1706       rse.ss = rss;
1707       gfc_conv_expr (&rse, expr2);
1708
1709       /* Form the expression of the temporary.  */
1710       lse.expr = gfc_build_array_ref (tmp1, count1);
1711     }
1712
1713   /* Use the scalar assignment.  */
1714   tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts.type);
1715
1716   /* Form the mask expression according to the mask tree list.  */
1717   if (wheremask)
1718     {
1719       wheremaskexpr = gfc_build_array_ref (wheremask, count3);
1720       tmp2 = TREE_CHAIN (wheremask);
1721       while (tmp2)
1722         {
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);
1727         }
1728       tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1729     }
1730
1731   gfc_add_expr_to_block (&body1, tmp);
1732
1733   if (lss == gfc_ss_terminator)
1734     {
1735       gfc_add_block_to_block (&block, &body1);
1736
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);
1741     }
1742   else
1743     {
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);
1748
1749       /* Increment count3.  */
1750       if (count3)
1751         {
1752           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
1753                              count3, gfc_index_one_node);
1754           gfc_add_modify_expr (&body1, count3, tmp);
1755         }
1756
1757       /* Generate the copying loops.  */
1758       gfc_trans_scalarizing_loops (&loop, &body1);
1759
1760       gfc_add_block_to_block (&block, &loop.pre);
1761       gfc_add_block_to_block (&block, &loop.post);
1762
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.  */
1766     }
1767
1768   tmp = gfc_finish_block (&block);
1769   return tmp;
1770 }
1771
1772
1773 /* Calculate the size of temporary needed in the assignment inside forall.
1774    LSS and RSS are filled in this function.  */
1775
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)
1780 {
1781   gfc_loopinfo loop;
1782   tree size;
1783   int i;
1784   tree tmp;
1785
1786   *lss = gfc_walk_expr (expr1);
1787   *rss = NULL;
1788
1789   size = gfc_index_one_node;
1790   if (*lss != gfc_ss_terminator)
1791     {
1792       gfc_init_loopinfo (&loop);
1793
1794       /* Walk the RHS of the expression.  */
1795       *rss = gfc_walk_expr (expr2);
1796       if (*rss == gfc_ss_terminator)
1797         {
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;
1803         }
1804
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);
1810
1811       /* We only want the shape of the expression, not rest of the junk
1812          generated by the scalarizer.  */
1813       loop.array_parameter = 1;
1814
1815       /* Calculate the bounds of the scalarization.  */
1816       gfc_conv_ss_startstride (&loop);
1817       gfc_conv_loop_setup (&loop);
1818
1819       /* Figure out how many elements we need.  */
1820       for (i = 0; i < loop.dimen; i++)
1821         {
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);
1827         }
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);
1831
1832       /* TODO: write a function that cleans up a loopinfo without freeing
1833          the SS chains.  Currently a NOP.  */
1834     }
1835
1836   return size;
1837 }
1838
1839
1840 /* Calculate the overall iterator number of the nested forall construct.  */
1841
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)
1845 {
1846   tree tmp, number;
1847   stmtblock_t body;
1848
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);
1852
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);
1863
1864   /* Generate loops.  */
1865   if (nested_forall_info != NULL)
1866     tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 0, 1);
1867
1868   gfc_add_expr_to_block (block, tmp);
1869
1870   return number;
1871 }
1872
1873
1874 /* Allocate temporary for forall construct.  SIZE is the size of temporary
1875    needed.  PTEMP1 is returned for space free.  */
1876
1877 static tree
1878 allocate_temp_for_forall_nest_1 (tree type, tree size, stmtblock_t * block,
1879                                  tree * ptemp1)
1880 {
1881   tree unit;
1882   tree temp1;
1883   tree tmp;
1884   tree bytesize;
1885
1886   unit = TYPE_SIZE_UNIT (type);
1887   bytesize = fold_build2 (MULT_EXPR, gfc_array_index_type, size, unit);
1888
1889   *ptemp1 = NULL;
1890   temp1 = gfc_do_allocate (bytesize, size, ptemp1, block, type);
1891
1892   if (*ptemp1)
1893     tmp = build_fold_indirect_ref (temp1);
1894   else
1895     tmp = temp1;
1896
1897   return tmp;
1898 }
1899
1900
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.  */
1904
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)
1909 {
1910   tree size;
1911
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);
1915
1916   return allocate_temp_for_forall_nest_1 (type, size, block, ptemp1);
1917 }
1918
1919
1920 /* Handle assignments inside forall which need temporary.
1921
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(:)
1929
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)
1938       {
1939         if (masktmp[maskindex++])
1940           tmp[count1++] = f<i>
1941       }
1942     maskindex = 0;
1943     count1 = 0;
1944     for (i = start; i <= end; i += stride)
1945       {
1946         if (masktmp[maskindex++])
1947           e<i> = tmp[count1++]
1948       }
1949     DEALLOCATE (tmp)
1950   */
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)
1955 {
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;
1963
1964   /* Create vars. count1 is the current iterator number of the nested
1965      forall.  */
1966   count1 = gfc_create_var (gfc_array_index_type, "count1");
1967
1968   /* Count is the wheremask index.  */
1969   if (wheremask)
1970     {
1971       count = gfc_create_var (gfc_array_index_type, "count");
1972       gfc_add_modify_expr (block, count, gfc_index_zero_node);
1973     }
1974   else
1975     count = NULL;
1976
1977   /* Initialize count1.  */
1978   gfc_add_modify_expr (block, count1, gfc_index_zero_node);
1979
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);
1985
1986   /* The type of LHS. Used in function allocate_temp_for_forall_nest */
1987   type = gfc_typenode_for_spec (&expr1->ts);
1988
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);
1993
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);
1997
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);
2002
2003   /* Reset count1.  */
2004   gfc_add_modify_expr (block, count1, gfc_index_zero_node);
2005
2006   /* Reset count.  */
2007   if (wheremask)
2008     gfc_add_modify_expr (block, count, gfc_index_zero_node);
2009
2010   /* Generate codes to copy the temporary to lhs.  */
2011   tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, count, count1, wheremask);
2012
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);
2017
2018   if (ptemp1)
2019     {
2020       /* Free the temporary.  */
2021       tmp = gfc_chainon_list (NULL_TREE, ptemp1);
2022       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
2023       gfc_add_expr_to_block (block, tmp);
2024     }
2025 }
2026
2027
2028 /* Translate pointer assignment inside FORALL which need temporary.  */
2029
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)
2034 {
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;
2048
2049   count = gfc_create_var (gfc_array_index_type, "count");
2050   gfc_add_modify_expr (block, count, gfc_index_zero_node);
2051
2052   inner_size = integer_one_node;
2053   lss = gfc_walk_expr (expr1);
2054   rss = gfc_walk_expr (expr2);
2055   if (lss == gfc_ss_terminator)
2056     {
2057       type = gfc_typenode_for_spec (&expr1->ts);
2058       type = build_pointer_type (type);
2059
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);
2073
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);
2078
2079       tmp = gfc_finish_block (&body);
2080
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);
2085
2086       /* Reset count.  */
2087       gfc_add_modify_expr (block, count, gfc_index_zero_node);
2088
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);
2103
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);
2108     }
2109   else
2110     {
2111       gfc_init_loopinfo (&loop);
2112
2113       /* Associate the SS with the loop.  */
2114       gfc_add_ss_to_loop (&loop, rss);
2115
2116       /* Setup the scalarizing loops and bounds.  */
2117       gfc_conv_ss_startstride (&loop);
2118
2119       gfc_conv_loop_setup (&loop);
2120
2121       info = &rss->data.info;
2122       desc = info->descriptor;
2123
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);
2128
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);
2138
2139       gfc_add_block_to_block (&body, &lse.pre);
2140       gfc_add_block_to_block (&body, &lse.post);
2141
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);
2146
2147       tmp = gfc_finish_block (&body);
2148
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);
2153
2154       /* Reset count.  */
2155       gfc_add_modify_expr (block, count, gfc_index_zero_node);
2156
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);
2165
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);
2170
2171       tmp = gfc_finish_block (&body);
2172
2173       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2174       gfc_add_expr_to_block (block, tmp);
2175     }
2176   /* Free the temporary.  */
2177   if (ptemp1)
2178     {
2179       tmp = gfc_chainon_list (NULL_TREE, ptemp1);
2180       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
2181       gfc_add_expr_to_block (block, tmp);
2182     }
2183 }
2184
2185
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.  */
2190
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.
2194
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(:)
2203
2204     maskindex = 0;
2205     for (i = start; i <= end; i += stride)
2206       {
2207         if (masktmp[maskindex++])
2208           e<i> = f<i>
2209       }
2210     maskindex = 0;
2211     for (i = start; i <= end; i += stride)
2212       {
2213         if (masktmp[maskindex++])
2214           g<i> = h<i>
2215       }
2216
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.
2222  */
2223
2224 static tree
2225 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
2226 {
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;
2254
2255   gfc_start_block (&block);
2256
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;
2262
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));
2270
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)
2275     {
2276       gfc_symbol *sym = fa->var->symtree->n.sym;
2277
2278       /* allocate space for this_forall.  */
2279       this_forall = (iter_info *) gfc_getmem (sizeof (iter_info));
2280
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]);
2285
2286       /* Record it in this_forall.  */
2287       this_forall->var = var[n];
2288
2289       /* Replace the index symbol's backend_decl with the temporary decl.  */
2290       sym->backend_decl = var[n];
2291
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;
2299
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;
2307
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;
2315
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
2322         {
2323           iter_tmp = info->this_loop;
2324           while (iter_tmp->next != NULL)
2325             iter_tmp = iter_tmp->next;
2326           iter_tmp->next = this_forall;
2327         }
2328
2329       n++;
2330     }
2331   nvar = n;
2332
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;
2338
2339   for (n = 0; n < nvar; n++)
2340     {
2341       if (lenvar && TREE_TYPE (lenvar) != TREE_TYPE (start[n]))
2342         lenvar = NULL_TREE;
2343
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);
2348
2349       tmp = fold_build2 (FLOOR_DIV_EXPR, TREE_TYPE (tmp), tmp, step[n]);
2350       tmp = convert (gfc_array_index_type, tmp);
2351
2352       size = fold_build2 (MULT_EXPR, gfc_array_index_type, size, tmp);
2353     }
2354
2355   /* Record the nvar and size of current forall level.  */
2356   info->nvar = nvar;
2357   info->size = size;
2358
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
2364     {
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;
2369     }
2370
2371   /* Copy the mask into a temporary variable if required.
2372      For now we assume a mask temporary is needed.  */
2373   if (code->expr)
2374     {
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);
2379
2380       /* Allocate the mask temporary.  */
2381       bytesize = fold_build2 (MULT_EXPR, gfc_array_index_type, size,
2382                               TYPE_SIZE_UNIT (smallest_boolean_type_node));
2383
2384       mask = gfc_do_allocate (bytesize, size, &pmask, &block,
2385                               smallest_boolean_type_node);
2386
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;
2392
2393       gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2394
2395       /* Start of mask assignment loop body.  */
2396       gfc_start_block (&body);
2397
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);
2402
2403       /* Store the mask.  */
2404       se.expr = convert (smallest_boolean_type_node, se.expr);
2405
2406       if (pmask)
2407         tmp = build_fold_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);
2412
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);
2417
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);
2422     }
2423   else
2424     {
2425       /* No mask was specified.  */
2426       maskindex = NULL_TREE;
2427       mask = pmask = NULL_TREE;
2428     }
2429
2430   c = code->block->next;
2431
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)
2435     {
2436       switch (c->op)
2437         {
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
2447             {
2448               /* Use the normal assignment copying routines.  */
2449               assign = gfc_trans_assignment (c->expr, c->expr2);
2450
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);
2454             }
2455
2456           break;
2457
2458         case EXEC_WHERE:
2459
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);
2463
2464           while (temp)
2465             {
2466               tree args;
2467               temporary_list *p;
2468
2469               /* Free the temporary.  */
2470               args = gfc_chainon_list (NULL_TREE, temp->temporary);
2471               tmp = build_function_call_expr (gfor_fndecl_internal_free, args);
2472               gfc_add_expr_to_block (&block, tmp);
2473
2474               p = temp;
2475               temp = temp->next;
2476               gfc_free (p);
2477             }
2478
2479           break;
2480
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
2488             {
2489               /* Use the normal assignment copying routines.  */
2490               assign = gfc_trans_pointer_assignment (c->expr, c->expr2);
2491
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);
2496             }
2497           break;
2498
2499         case EXEC_FORALL:
2500           tmp = gfc_trans_forall_1 (c, nested_forall_info);
2501           gfc_add_expr_to_block (&block, tmp);
2502           break;
2503
2504         default:
2505           gcc_unreachable ();
2506         }
2507
2508       c = c->next;
2509     }
2510
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]);
2514
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);
2522
2523   if (pmask)
2524     {
2525       /* Free the temporary for the mask.  */
2526       tmp = gfc_chainon_list (NULL_TREE, pmask);
2527       tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
2528       gfc_add_expr_to_block (&block, tmp);
2529     }
2530   if (maskindex)
2531     pushdecl (maskindex);
2532
2533   return gfc_finish_block (&block);
2534 }
2535
2536
2537 /* Translate the FORALL statement or construct.  */
2538
2539 tree gfc_trans_forall (gfc_code * code)
2540 {
2541   return gfc_trans_forall_1 (code, NULL);
2542 }
2543
2544
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.  */
2555
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)
2560 {
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;
2570
2571   gfc_init_loopinfo (&loop);
2572
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);
2576
2577   /* Calculate the total size of temporary needed.  */
2578   size = compute_overall_iter_number (nested_forall_info, inner_size,
2579                                       &inner_size_body, block);
2580
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)
2586     {
2587       temporary_list *tempo;
2588       tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2589       tempo->temporary = ptemp1;
2590       tempo->next = *temp;
2591       *temp = tempo;
2592     }
2593
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)
2599     {
2600       temporary_list *tempo;
2601       tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2602       tempo->temporary = ptemp2;
2603       tempo->next = *temp;
2604       *temp = tempo;
2605     }
2606
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);
2611
2612   gfc_start_block (&body);
2613
2614   gfc_init_se (&rse, NULL);
2615   gfc_init_se (&lse, NULL);
2616
2617   if (lss == gfc_ss_terminator)
2618     {
2619       gfc_init_block (&body1);
2620     }
2621   else
2622     {
2623       /* Initialize the loop.  */
2624       gfc_init_loopinfo (&loop);
2625
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);
2629
2630       gfc_conv_ss_startstride (&loop);
2631       gfc_conv_loop_setup (&loop);
2632
2633       gfc_mark_ss_chain_used (rss, 1);
2634       /* Start the loop body.  */
2635       gfc_start_scalarized_body (&loop, &body1);
2636
2637       /* Translate the expression.  */
2638       gfc_copy_loopinfo_to_se (&rse, &loop);
2639       rse.ss = rss;
2640       gfc_conv_expr (&rse, me);
2641     }
2642   /* Form the expression of the temporary.  */
2643   lse.expr = gfc_build_array_ref (tmp, count);
2644   tmpexpr = gfc_build_array_ref (ntmp, count);
2645
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);
2649
2650   /* Fill temporary NTMP.  */
2651   tmp1 = build1 (TRUTH_NOT_EXPR, TREE_TYPE (lse.expr), lse.expr);
2652   gfc_add_modify_expr (&body1, tmpexpr, tmp1);
2653
2654  if (lss == gfc_ss_terminator)
2655     {
2656       gfc_add_block_to_block (&body, &body1);
2657     }
2658   else
2659     {
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);
2664
2665       /* Generate the copying loops.  */
2666       gfc_trans_scalarizing_loops (&loop, &body1);
2667
2668       gfc_add_block_to_block (&body, &loop.pre);
2669       gfc_add_block_to_block (&body, &loop.post);
2670
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.  */
2674     }
2675
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);
2680
2681   gfc_add_expr_to_block (block, tmp1);
2682
2683   *mask = tmp;
2684   *nmask = ntmp;
2685
2686   return tmp1;
2687 }
2688
2689
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.  */
2693
2694 static tree
2695 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2, tree mask,
2696                         tree count1, tree count2)
2697 {
2698   gfc_se lse;
2699   gfc_se rse;
2700   gfc_ss *lss;
2701   gfc_ss *lss_section;
2702   gfc_ss *rss;
2703
2704   gfc_loopinfo loop;
2705   tree tmp;
2706   stmtblock_t block;
2707   stmtblock_t body;
2708   tree index, maskexpr, tmp1;
2709
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)
2714     {
2715       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2716       if (tmp)
2717         return tmp;
2718     }
2719 #endif
2720
2721  /* Assignment of the form lhs = rhs.  */
2722   gfc_start_block (&block);
2723
2724   gfc_init_se (&lse, NULL);
2725   gfc_init_se (&rse, NULL);
2726
2727   /* Walk the lhs.  */
2728   lss = gfc_walk_expr (expr1);
2729   rss = NULL;
2730
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);
2734
2735   /* The assignment needs scalarization.  */
2736   lss_section = lss;
2737
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;
2742
2743   gcc_assert (lss_section != gfc_ss_terminator);
2744
2745   /* Initialize the scalarizer.  */
2746   gfc_init_loopinfo (&loop);
2747
2748   /* Walk the rhs.  */
2749   rss = gfc_walk_expr (expr2);
2750   if (rss == gfc_ss_terminator)
2751    {
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;
2757     }
2758
2759   /* Associate the SS with the loop.  */
2760   gfc_add_ss_to_loop (&loop, lss);
2761   gfc_add_ss_to_loop (&loop, rss);
2762
2763   /* Calculate the bounds of the scalarization.  */
2764   gfc_conv_ss_startstride (&loop);
2765
2766   /* Resolve any data dependencies in the statement.  */
2767   gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2768
2769   /* Setup the scalarizing loops.  */
2770   gfc_conv_loop_setup (&loop);
2771
2772   /* Setup the gfc_se structures.  */
2773   gfc_copy_loopinfo_to_se (&lse, &loop);
2774   gfc_copy_loopinfo_to_se (&rse, &loop);
2775
2776   rse.ss = rss;
2777   gfc_mark_ss_chain_used (rss, 1);
2778   if (loop.temp_ss == NULL)
2779     {
2780       lse.ss = lss;
2781       gfc_mark_ss_chain_used (lss, 1);
2782     }
2783   else
2784     {
2785       lse.ss = loop.temp_ss;
2786       gfc_mark_ss_chain_used (lss, 3);
2787       gfc_mark_ss_chain_used (loop.temp_ss, 3);
2788     }
2789
2790   /* Start the scalarized loop body.  */
2791   gfc_start_scalarized_body (&loop, &body);
2792
2793   /* Translate the expression.  */
2794   gfc_conv_expr (&rse, expr2);
2795   if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2796     {
2797       gfc_conv_tmp_array_ref (&lse);
2798       gfc_advance_se_ss_chain (&lse);
2799     }
2800   else
2801     gfc_conv_expr (&lse, expr1);
2802
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;
2810
2811   tmp = TREE_CHAIN (tmp);
2812   while (tmp)
2813     {
2814       tmp1 = gfc_build_array_ref (tmp, index);
2815       maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1), maskexpr, tmp1);
2816       tmp = TREE_CHAIN (tmp);
2817     }
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 ());
2821
2822   gfc_add_expr_to_block (&body, tmp);
2823
2824   if (lss == gfc_ss_terminator)
2825     {
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);
2830
2831       /* Use the scalar assignment as is.  */
2832       gfc_add_block_to_block (&block, &body);
2833     }
2834   else
2835     {
2836       gcc_assert (lse.ss == gfc_ss_terminator
2837                   && rse.ss == gfc_ss_terminator);
2838
2839       if (loop.temp_ss != NULL)
2840         {
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);
2847
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);
2853
2854           rse.ss = loop.temp_ss;
2855           lse.ss = lss;
2856
2857           gfc_conv_tmp_array_ref (&rse);
2858           gfc_advance_se_ss_chain (&rse);
2859           gfc_conv_expr (&lse, expr1);
2860
2861           gcc_assert (lse.ss == gfc_ss_terminator
2862                       && rse.ss == gfc_ss_terminator);
2863
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;
2871
2872           tmp = TREE_CHAIN (tmp);
2873           while (tmp)
2874             {
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);
2879             }
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);
2884
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);
2889         }
2890       else
2891         {
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);
2896         }
2897
2898       /* Generate the copying loops.  */
2899       gfc_trans_scalarizing_loops (&loop, &body);
2900
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);
2905     }
2906
2907   return gfc_finish_block (&block);
2908 }
2909
2910
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.  */
2916
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)
2921 {
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;
2930
2931   /* the WHERE statement or the WHERE construct statement.  */
2932   cblock = code->block;
2933   while (cblock)
2934     {
2935       /* Has mask-expr.  */
2936       if (cblock->expr)
2937         {
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);
2941
2942           /* Set the control mask and the pending control mask.  */
2943           /* It's a where-stmt.  */
2944           if (mask == NULL)
2945             {
2946               mask = tmp;
2947               pmask = tmp1;
2948             }
2949           /* It's a nested where-stmt.  */
2950           else if (mask && pmask == NULL)
2951             {
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);
2957             }
2958           /* It's a masked-elsewhere-stmt.  */
2959           else if (mask && cblock->expr)
2960             {
2961               tree tmp2;
2962               tmp2 = copy_list (pmask);
2963
2964               mask = pmask;
2965               tmp2 = chainon (tmp2, tmp);
2966               pmask = chainon (mask, tmp1);
2967               mask = tmp2;
2968             }
2969         }
2970       /* It's a elsewhere-stmt. No mask-expr is present.  */
2971       else
2972         mask = pmask;
2973
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)
2978         {
2979           switch (cnext->op)
2980             {
2981             /* WHERE assignment statement.  */
2982             case EXEC_ASSIGN:
2983               expr1 = cnext->expr;
2984               expr2 = cnext->expr2;
2985               if (nested_forall_info != NULL)
2986                 {
2987                   int nvar;
2988                   gfc_expr **varexpr;
2989
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
2999                     {
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);
3005
3006                       tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3007                                                     count2);
3008
3009                       tmp = gfc_trans_nested_forall_loop (nested_forall_info,
3010                                                           tmp, 1, 1);
3011                       gfc_add_expr_to_block (block, tmp);
3012                     }
3013                 }
3014               else
3015                 {
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);
3021
3022                   tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3023                                                 count2);
3024                   gfc_add_expr_to_block (block, tmp);
3025
3026                 }
3027               break;
3028
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;
3036
3037             default:
3038               gcc_unreachable ();
3039             }
3040
3041          /* The next statement within the same where-body-construct.  */
3042          cnext = cnext->next;
3043        }
3044     /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt.  */
3045     cblock = cblock->block;
3046   }
3047 }
3048
3049
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.  */
3053
3054 tree
3055 gfc_trans_where (gfc_code * code)
3056 {
3057   stmtblock_t block;
3058   temporary_list *temp, *p;
3059   tree args;
3060   tree tmp;
3061
3062   gfc_start_block (&block);
3063   temp = NULL;
3064
3065   gfc_trans_where_2 (code, NULL, NULL, NULL, &block, &temp);
3066
3067   /* Add calls to free temporaries which were dynamically allocated.  */
3068   while (temp)
3069     {
3070       args = gfc_chainon_list (NULL_TREE, temp->temporary);
3071       tmp = build_function_call_expr (gfor_fndecl_internal_free, args);
3072       gfc_add_expr_to_block (&block, tmp);
3073
3074       p = temp;
3075       temp = temp->next;
3076       gfc_free (p);
3077     }
3078   return gfc_finish_block (&block);
3079 }
3080
3081
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.  */
3085
3086 tree
3087 gfc_trans_cycle (gfc_code * code)
3088 {
3089   tree cycle_label;
3090
3091   cycle_label = TREE_PURPOSE (code->ext.whichloop->backend_decl);
3092   TREE_USED (cycle_label) = 1;
3093   return build1_v (GOTO_EXPR, cycle_label);
3094 }
3095
3096
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.  */
3100
3101 tree
3102 gfc_trans_exit (gfc_code * code)
3103 {
3104   tree exit_label;
3105
3106   exit_label = TREE_VALUE (code->ext.whichloop->backend_decl);
3107   TREE_USED (exit_label) = 1;
3108   return build1_v (GOTO_EXPR, exit_label);
3109 }
3110
3111
3112 /* Translate the ALLOCATE statement.  */
3113
3114 tree
3115 gfc_trans_allocate (gfc_code * code)
3116 {
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;
3127
3128   if (!code->ext.alloc_list)
3129     return NULL_TREE;
3130
3131   gfc_start_block (&block);
3132
3133   if (code->expr)
3134     {
3135       tree gfc_int4_type_node = gfc_get_int_type (4);
3136
3137       stat = gfc_create_var (gfc_int4_type_node, "stat");
3138       pstat = build_fold_addr_expr (stat);
3139
3140       error_label = gfc_build_label_decl (NULL_TREE);
3141       TREE_USED (error_label) = 1;
3142     }
3143   else
3144     {
3145       pstat = integer_zero_node;
3146       stat = error_label = NULL_TREE;
3147     }
3148
3149
3150   for (al = code->ext.alloc_list; al != NULL; al = al->next)
3151     {
3152       expr = al->expr;
3153
3154       gfc_init_se (&se, NULL);
3155       gfc_start_block (&se.pre);
3156
3157       se.want_pointer = 1;
3158       se.descriptor_only = 1;
3159       gfc_conv_expr (&se, expr);
3160
3161       ref = expr->ref;
3162
3163       /* Find the last reference in the chain.  */
3164       while (ref && ref->next != NULL)
3165         {
3166           gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3167           ref = ref->next;
3168         }
3169
3170       if (ref != NULL && ref->type == REF_ARRAY)
3171         {
3172           /* An array.  */
3173           gfc_array_allocate (&se, ref, pstat);
3174         }
3175       else
3176         {
3177           /* A scalar or derived type.  */
3178           tree val;
3179
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);
3183
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 = build_function_call_expr (gfor_fndecl_allocate, parm);
3189           gfc_add_expr_to_block (&se.pre, tmp);
3190
3191           if (code->expr)
3192             {
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);
3198             }
3199         }
3200
3201       tmp = gfc_finish_block (&se.pre);
3202       gfc_add_expr_to_block (&block, tmp);
3203     }
3204
3205   /* Assign the value to the status variable.  */
3206   if (code->expr)
3207     {
3208       tmp = build1_v (LABEL_EXPR, error_label);
3209       gfc_add_expr_to_block (&block, tmp);
3210
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);
3215     }
3216
3217   return gfc_finish_block (&block);
3218 }
3219
3220
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)
3240 {
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;
3246
3247   gfc_start_block (&block);
3248
3249   /* Set up the optional STAT= */
3250   if (code->expr)
3251     {
3252       tree gfc_int4_type_node = gfc_get_int_type (4);
3253
3254       /* Variable used with the library call.  */
3255       stat = gfc_create_var (gfc_int4_type_node, "stat");
3256       pstat = build_fold_addr_expr (stat);
3257
3258       /* Running total of possible deallocation failures.  */
3259       astat = gfc_create_var (gfc_int4_type_node, "astat");
3260       apstat = build_fold_addr_expr (astat);
3261
3262       /* Initialize astat to 0.  */
3263       gfc_add_modify_expr (&block, astat, build_int_cst (TREE_TYPE (astat), 0));
3264     }
3265   else
3266     {
3267       pstat = apstat = null_pointer_node;
3268       stat = astat = NULL_TREE;
3269     }
3270
3271   for (al = code->ext.alloc_list; al != NULL; al = al->next)
3272     {
3273       expr = al->expr;
3274       gcc_assert (expr->expr_type == EXPR_VARIABLE);
3275
3276       gfc_init_se (&se, NULL);
3277       gfc_start_block (&se.pre);
3278
3279       se.want_pointer = 1;
3280       se.descriptor_only = 1;
3281       gfc_conv_expr (&se, expr);
3282
3283       if (expr->rank)
3284         tmp = gfc_array_deallocate (se.expr, pstat);
3285       else
3286         {
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);
3291
3292           parm = gfc_chainon_list (NULL_TREE, var);
3293           parm = gfc_chainon_list (parm, pstat);
3294           tmp = build_function_call_expr (gfor_fndecl_deallocate, parm);
3295         }
3296
3297       gfc_add_expr_to_block (&se.pre, tmp);
3298
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)
3302         {
3303           apstat = build2 (PLUS_EXPR, TREE_TYPE (stat), astat, stat);
3304           gfc_add_modify_expr (&se.pre, astat, apstat);
3305         }
3306
3307       tmp = gfc_finish_block (&se.pre);
3308       gfc_add_expr_to_block (&block, tmp);
3309
3310     }
3311
3312   /* Assign the value to the status variable.  */
3313   if (code->expr)
3314     {
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);
3319     }
3320
3321   return gfc_finish_block (&block);
3322 }
3323