OSDN Git Service

fortran/
[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, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, 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 int has_alternate_specifier;
41
42 typedef struct iter_info
43 {
44   tree var;
45   tree start;
46   tree end;
47   tree step;
48   struct iter_info *next;
49 }
50 iter_info;
51
52 typedef  struct temporary_list
53 {
54   tree temporary;
55   struct temporary_list *next;
56 }
57 temporary_list;
58
59 typedef struct forall_info
60 {
61   iter_info *this_loop;
62   tree mask;
63   tree pmask;
64   tree maskindex;
65   int nvar;
66   tree size;
67   struct forall_info  *outer;
68   struct forall_info  *next_nest;
69 }
70 forall_info;
71
72 static void gfc_trans_where_2 (gfc_code *, tree, tree, forall_info *,
73                                stmtblock_t *, temporary_list **temp);
74
75 /* Translate a F95 label number to a LABEL_EXPR.  */
76
77 tree
78 gfc_trans_label_here (gfc_code * code)
79 {
80   return build1_v (LABEL_EXPR, gfc_get_label_decl (code->here));
81 }
82
83
84 /* Given a variable expression which has been ASSIGNed to, find the decl
85    containing the auxiliary variables.  For variables in common blocks this
86    is a field_decl.  */
87
88 void
89 gfc_conv_label_variable (gfc_se * se, gfc_expr * expr)
90 {
91   gcc_assert (expr->symtree->n.sym->attr.assign == 1);
92   gfc_conv_expr (se, expr);
93   /* Deals with variable in common block. Get the field declaration.  */
94   if (TREE_CODE (se->expr) == COMPONENT_REF)
95     se->expr = TREE_OPERAND (se->expr, 1);
96 }
97
98 /* Translate a label assignment statement.  */
99
100 tree
101 gfc_trans_label_assign (gfc_code * code)
102 {
103   tree label_tree;
104   gfc_se se;
105   tree len;
106   tree addr;
107   tree len_tree;
108   char *label_str;
109   int label_len;
110
111   /* Start a new block.  */
112   gfc_init_se (&se, NULL);
113   gfc_start_block (&se.pre);
114   gfc_conv_label_variable (&se, code->expr);
115
116   len = GFC_DECL_STRING_LEN (se.expr);
117   addr = GFC_DECL_ASSIGN_ADDR (se.expr);
118
119   label_tree = gfc_get_label_decl (code->label);
120
121   if (code->label->defined == ST_LABEL_TARGET)
122     {
123       /* Shouldn't need to set this flag. Reserve for optimization bug.  */
124       DECL_ARTIFICIAL (label_tree) = 0;
125       label_tree = gfc_build_addr_expr (pvoid_type_node, label_tree);
126       len_tree = integer_minus_one_node;
127     }
128   else
129     {
130       label_str = code->label->format->value.character.string;
131       label_len = code->label->format->value.character.length;
132       len_tree = build_int_cst (NULL_TREE, label_len);
133       label_tree = gfc_build_string_const (label_len + 1, label_str);
134       label_tree = gfc_build_addr_expr (pchar_type_node, label_tree);
135     }
136
137   gfc_add_modify_expr (&se.pre, len, len_tree);
138   gfc_add_modify_expr (&se.pre, addr, label_tree);
139
140   return gfc_finish_block (&se.pre);
141 }
142
143 /* Translate a GOTO statement.  */
144
145 tree
146 gfc_trans_goto (gfc_code * code)
147 {
148   tree assigned_goto;
149   tree target;
150   tree tmp;
151   tree assign_error;
152   tree range_error;
153   gfc_se se;
154
155
156   if (code->label != NULL)
157     return build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
158
159   /* ASSIGNED GOTO.  */
160   gfc_init_se (&se, NULL);
161   gfc_start_block (&se.pre);
162   gfc_conv_label_variable (&se, code->expr);
163   assign_error =
164     gfc_build_cstring_const ("Assigned label is not a target label");
165   tmp = GFC_DECL_STRING_LEN (se.expr);
166   tmp = build2 (NE_EXPR, boolean_type_node, tmp, integer_minus_one_node);
167   gfc_trans_runtime_check (tmp, assign_error, &se.pre);
168
169   assigned_goto = GFC_DECL_ASSIGN_ADDR (se.expr);
170   target = build1 (GOTO_EXPR, void_type_node, assigned_goto);
171
172   code = code->block;
173   if (code == NULL)
174     {
175       gfc_add_expr_to_block (&se.pre, target);
176       return gfc_finish_block (&se.pre);
177     }
178
179   /* Check the label list.  */
180   range_error = gfc_build_cstring_const ("Assigned label is not in the list");
181
182   do
183     {
184       tmp = gfc_get_label_decl (code->label);
185       tmp = gfc_build_addr_expr (pvoid_type_node, tmp);
186       tmp = build2 (EQ_EXPR, boolean_type_node, tmp, assigned_goto);
187       tmp = build3_v (COND_EXPR, tmp, target, build_empty_stmt ());
188       gfc_add_expr_to_block (&se.pre, tmp);
189       code = code->block;
190     }
191   while (code != NULL);
192   gfc_trans_runtime_check (boolean_true_node, range_error, &se.pre);
193   return gfc_finish_block (&se.pre); 
194 }
195
196
197 /* Translate an ENTRY statement.  Just adds a label for this entry point.  */
198 tree
199 gfc_trans_entry (gfc_code * code)
200 {
201   return build1_v (LABEL_EXPR, code->ext.entry->label);
202 }
203
204
205 /* Translate the CALL statement.  Builds a call to an F95 subroutine.  */
206
207 tree
208 gfc_trans_call (gfc_code * code)
209 {
210   gfc_se se;
211
212   /* A CALL starts a new block because the actual arguments may have to
213      be evaluated first.  */
214   gfc_init_se (&se, NULL);
215   gfc_start_block (&se.pre);
216
217   gcc_assert (code->resolved_sym);
218   has_alternate_specifier = 0;
219
220   /* Translate the call.  */
221   gfc_conv_function_call (&se, code->resolved_sym, code->ext.actual);
222
223   /* A subroutine without side-effect, by definition, does nothing!  */
224   TREE_SIDE_EFFECTS (se.expr) = 1;
225
226   /* Chain the pieces together and return the block.  */
227   if (has_alternate_specifier)
228     {
229       gfc_code *select_code;
230       gfc_symbol *sym;
231       select_code = code->next;
232       gcc_assert(select_code->op == EXEC_SELECT);
233       sym = select_code->expr->symtree->n.sym;
234       se.expr = convert (gfc_typenode_for_spec (&sym->ts), se.expr);
235       gfc_add_modify_expr (&se.pre, sym->backend_decl, se.expr);
236     }
237   else
238     gfc_add_expr_to_block (&se.pre, se.expr);
239
240   gfc_add_block_to_block (&se.pre, &se.post);
241   return gfc_finish_block (&se.pre);
242 }
243
244
245 /* Translate the RETURN statement.  */
246
247 tree
248 gfc_trans_return (gfc_code * code ATTRIBUTE_UNUSED)
249 {
250   if (code->expr)
251     {
252       gfc_se se;
253       tree tmp;
254       tree result;
255
256       /* if code->expr is not NULL, this return statement must appear
257          in a subroutine and current_fake_result_decl has already
258          been generated.  */
259
260       result = gfc_get_fake_result_decl (NULL);
261       if (!result)
262         {
263           gfc_warning ("An alternate return at %L without a * dummy argument",
264                         &code->expr->where);
265           return build1_v (GOTO_EXPR, gfc_get_return_label ());
266         }
267
268       /* Start a new block for this statement.  */
269       gfc_init_se (&se, NULL);
270       gfc_start_block (&se.pre);
271
272       gfc_conv_expr (&se, code->expr);
273
274       tmp = build2 (MODIFY_EXPR, TREE_TYPE (result), result, se.expr);
275       gfc_add_expr_to_block (&se.pre, tmp);
276
277       tmp = build1_v (GOTO_EXPR, gfc_get_return_label ());
278       gfc_add_expr_to_block (&se.pre, tmp);
279       gfc_add_block_to_block (&se.pre, &se.post);
280       return gfc_finish_block (&se.pre);
281     }
282   else
283     return build1_v (GOTO_EXPR, gfc_get_return_label ());
284 }
285
286
287 /* Translate the PAUSE statement.  We have to translate this statement
288    to a runtime library call.  */
289
290 tree
291 gfc_trans_pause (gfc_code * code)
292 {
293   tree gfc_int4_type_node = gfc_get_int_type (4);
294   gfc_se se;
295   tree args;
296   tree tmp;
297   tree fndecl;
298
299   /* Start a new block for this statement.  */
300   gfc_init_se (&se, NULL);
301   gfc_start_block (&se.pre);
302
303
304   if (code->expr == NULL)
305     {
306       tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
307       args = gfc_chainon_list (NULL_TREE, tmp);
308       fndecl = gfor_fndecl_pause_numeric;
309     }
310   else
311     {
312       gfc_conv_expr_reference (&se, code->expr);
313       args = gfc_chainon_list (NULL_TREE, se.expr);
314       args = gfc_chainon_list (args, se.string_length);
315       fndecl = gfor_fndecl_pause_string;
316     }
317
318   tmp = gfc_build_function_call (fndecl, args);
319   gfc_add_expr_to_block (&se.pre, tmp);
320
321   gfc_add_block_to_block (&se.pre, &se.post);
322
323   return gfc_finish_block (&se.pre);
324 }
325
326
327 /* Translate the STOP statement.  We have to translate this statement
328    to a runtime library call.  */
329
330 tree
331 gfc_trans_stop (gfc_code * code)
332 {
333   tree gfc_int4_type_node = gfc_get_int_type (4);
334   gfc_se se;
335   tree args;
336   tree tmp;
337   tree fndecl;
338
339   /* Start a new block for this statement.  */
340   gfc_init_se (&se, NULL);
341   gfc_start_block (&se.pre);
342
343
344   if (code->expr == NULL)
345     {
346       tmp = build_int_cst (gfc_int4_type_node, code->ext.stop_code);
347       args = gfc_chainon_list (NULL_TREE, tmp);
348       fndecl = gfor_fndecl_stop_numeric;
349     }
350   else
351     {
352       gfc_conv_expr_reference (&se, code->expr);
353       args = gfc_chainon_list (NULL_TREE, se.expr);
354       args = gfc_chainon_list (args, se.string_length);
355       fndecl = gfor_fndecl_stop_string;
356     }
357
358   tmp = gfc_build_function_call (fndecl, args);
359   gfc_add_expr_to_block (&se.pre, tmp);
360
361   gfc_add_block_to_block (&se.pre, &se.post);
362
363   return gfc_finish_block (&se.pre);
364 }
365
366
367 /* Generate GENERIC for the IF construct. This function also deals with
368    the simple IF statement, because the front end translates the IF
369    statement into an IF construct.
370
371    We translate:
372
373         IF (cond) THEN
374            then_clause
375         ELSEIF (cond2)
376            elseif_clause
377         ELSE
378            else_clause
379         ENDIF
380
381    into:
382
383         pre_cond_s;
384         if (cond_s)
385           {
386             then_clause;
387           }
388         else
389           {
390             pre_cond_s
391             if (cond_s)
392               {
393                 elseif_clause
394               }
395             else
396               {
397                 else_clause;
398               }
399           }
400
401    where COND_S is the simplified version of the predicate. PRE_COND_S
402    are the pre side-effects produced by the translation of the
403    conditional.
404    We need to build the chain recursively otherwise we run into
405    problems with folding incomplete statements.  */
406
407 static tree
408 gfc_trans_if_1 (gfc_code * code)
409 {
410   gfc_se if_se;
411   tree stmt, elsestmt;
412
413   /* Check for an unconditional ELSE clause.  */
414   if (!code->expr)
415     return gfc_trans_code (code->next);
416
417   /* Initialize a statement builder for each block. Puts in NULL_TREEs.  */
418   gfc_init_se (&if_se, NULL);
419   gfc_start_block (&if_se.pre);
420
421   /* Calculate the IF condition expression.  */
422   gfc_conv_expr_val (&if_se, code->expr);
423
424   /* Translate the THEN clause.  */
425   stmt = gfc_trans_code (code->next);
426
427   /* Translate the ELSE clause.  */
428   if (code->block)
429     elsestmt = gfc_trans_if_1 (code->block);
430   else
431     elsestmt = build_empty_stmt ();
432
433   /* Build the condition expression and add it to the condition block.  */
434   stmt = build3_v (COND_EXPR, if_se.expr, stmt, elsestmt);
435   
436   gfc_add_expr_to_block (&if_se.pre, stmt);
437
438   /* Finish off this statement.  */
439   return gfc_finish_block (&if_se.pre);
440 }
441
442 tree
443 gfc_trans_if (gfc_code * code)
444 {
445   /* Ignore the top EXEC_IF, it only announces an IF construct. The
446      actual code we must translate is in code->block.  */
447
448   return gfc_trans_if_1 (code->block);
449 }
450
451
452 /* Translage an arithmetic IF expression.
453
454    IF (cond) label1, label2, label3 translates to
455
456     if (cond <= 0)
457       {
458         if (cond < 0)
459           goto label1;
460         else // cond == 0
461           goto label2;
462       }
463     else // cond > 0
464       goto label3;
465 */
466
467 tree
468 gfc_trans_arithmetic_if (gfc_code * code)
469 {
470   gfc_se se;
471   tree tmp;
472   tree branch1;
473   tree branch2;
474   tree zero;
475
476   /* Start a new block.  */
477   gfc_init_se (&se, NULL);
478   gfc_start_block (&se.pre);
479
480   /* Pre-evaluate COND.  */
481   gfc_conv_expr_val (&se, code->expr);
482
483   /* Build something to compare with.  */
484   zero = gfc_build_const (TREE_TYPE (se.expr), integer_zero_node);
485
486   /* If (cond < 0) take branch1 else take branch2.
487      First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases.  */
488   branch1 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label));
489   branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label2));
490
491   tmp = build2 (LT_EXPR, boolean_type_node, se.expr, zero);
492   branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
493
494   /* if (cond <= 0) take branch1 else take branch2.  */
495   branch2 = build1_v (GOTO_EXPR, gfc_get_label_decl (code->label3));
496   tmp = build2 (LE_EXPR, boolean_type_node, se.expr, zero);
497   branch1 = build3_v (COND_EXPR, tmp, branch1, branch2);
498
499   /* Append the COND_EXPR to the evaluation of COND, and return.  */
500   gfc_add_expr_to_block (&se.pre, branch1);
501   return gfc_finish_block (&se.pre);
502 }
503
504
505 /* Translate the simple DO construct.  This is where the loop variable has
506    integer type and step +-1.  We can't use this in the general case
507    because integer overflow and floating point errors could give incorrect
508    results.
509    We translate a do loop from:
510
511    DO dovar = from, to, step
512       body
513    END DO
514
515    to:
516
517    [Evaluate loop bounds and step]
518    dovar = from;
519    if ((step > 0) ? (dovar <= to) : (dovar => to))
520     {
521       for (;;)
522         {
523           body;
524    cycle_label:
525           cond = (dovar == to);
526           dovar += step;
527           if (cond) goto end_label;
528         }
529       }
530    end_label:
531
532    This helps the optimizers by avoiding the extra induction variable
533    used in the general case.  */
534
535 static tree
536 gfc_trans_simple_do (gfc_code * code, stmtblock_t *pblock, tree dovar,
537                      tree from, tree to, tree step)
538 {
539   stmtblock_t body;
540   tree type;
541   tree cond;
542   tree tmp;
543   tree cycle_label;
544   tree exit_label;
545   
546   type = TREE_TYPE (dovar);
547
548   /* Initialize the DO variable: dovar = from.  */
549   gfc_add_modify_expr (pblock, dovar, from);
550
551   /* Cycle and exit statements are implemented with gotos.  */
552   cycle_label = gfc_build_label_decl (NULL_TREE);
553   exit_label = gfc_build_label_decl (NULL_TREE);
554
555   /* Put the labels where they can be found later. See gfc_trans_do().  */
556   code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
557
558   /* Loop body.  */
559   gfc_start_block (&body);
560
561   /* Main loop body.  */
562   tmp = gfc_trans_code (code->block->next);
563   gfc_add_expr_to_block (&body, tmp);
564
565   /* Label for cycle statements (if needed).  */
566   if (TREE_USED (cycle_label))
567     {
568       tmp = build1_v (LABEL_EXPR, cycle_label);
569       gfc_add_expr_to_block (&body, tmp);
570     }
571
572   /* Evaluate the loop condition.  */
573   cond = build2 (EQ_EXPR, boolean_type_node, dovar, to);
574   cond = gfc_evaluate_now (cond, &body);
575
576   /* Increment the loop variable.  */
577   tmp = build2 (PLUS_EXPR, type, dovar, step);
578   gfc_add_modify_expr (&body, dovar, tmp);
579
580   /* The loop exit.  */
581   tmp = build1_v (GOTO_EXPR, exit_label);
582   TREE_USED (exit_label) = 1;
583   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
584   gfc_add_expr_to_block (&body, tmp);
585
586   /* Finish the loop body.  */
587   tmp = gfc_finish_block (&body);
588   tmp = build1_v (LOOP_EXPR, tmp);
589
590   /* Only execute the loop if the number of iterations is positive.  */
591   if (tree_int_cst_sgn (step) > 0)
592     cond = fold (build2 (LE_EXPR, boolean_type_node, dovar, to));
593   else
594     cond = fold (build2 (GE_EXPR, boolean_type_node, dovar, to));
595   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
596   gfc_add_expr_to_block (pblock, tmp);
597
598   /* Add the exit label.  */
599   tmp = build1_v (LABEL_EXPR, exit_label);
600   gfc_add_expr_to_block (pblock, tmp);
601
602   return gfc_finish_block (pblock);
603 }
604
605 /* Translate the DO construct.  This obviously is one of the most
606    important ones to get right with any compiler, but especially
607    so for Fortran.
608
609    We special case some loop forms as described in gfc_trans_simple_do.
610    For other cases we implement them with a separate loop count,
611    as described in the standard.
612
613    We translate a do loop from:
614
615    DO dovar = from, to, step
616       body
617    END DO
618
619    to:
620
621    [evaluate loop bounds and step]
622    count = to + step - from;
623    dovar = from;
624    for (;;)
625      {
626        body;
627 cycle_label:
628        dovar += step
629        count--;
630        if (count <=0) goto exit_label;
631      }
632 exit_label:
633
634    TODO: Large loop counts
635    The code above assumes the loop count fits into a signed integer kind,
636    i.e. Does not work for loop counts > 2^31 for integer(kind=4) variables
637    We must support the full range.  */
638
639 tree
640 gfc_trans_do (gfc_code * code)
641 {
642   gfc_se se;
643   tree dovar;
644   tree from;
645   tree to;
646   tree step;
647   tree count;
648   tree count_one;
649   tree type;
650   tree cond;
651   tree cycle_label;
652   tree exit_label;
653   tree tmp;
654   stmtblock_t block;
655   stmtblock_t body;
656
657   gfc_start_block (&block);
658
659   /* Evaluate all the expressions in the iterator.  */
660   gfc_init_se (&se, NULL);
661   gfc_conv_expr_lhs (&se, code->ext.iterator->var);
662   gfc_add_block_to_block (&block, &se.pre);
663   dovar = se.expr;
664   type = TREE_TYPE (dovar);
665
666   gfc_init_se (&se, NULL);
667   gfc_conv_expr_val (&se, code->ext.iterator->start);
668   gfc_add_block_to_block (&block, &se.pre);
669   from = gfc_evaluate_now (se.expr, &block);
670
671   gfc_init_se (&se, NULL);
672   gfc_conv_expr_val (&se, code->ext.iterator->end);
673   gfc_add_block_to_block (&block, &se.pre);
674   to = gfc_evaluate_now (se.expr, &block);
675
676   gfc_init_se (&se, NULL);
677   gfc_conv_expr_val (&se, code->ext.iterator->step);
678   gfc_add_block_to_block (&block, &se.pre);
679   step = gfc_evaluate_now (se.expr, &block);
680
681   /* Special case simple loops.  */
682   if (TREE_CODE (type) == INTEGER_TYPE
683       && (integer_onep (step)
684         || tree_int_cst_equal (step, integer_minus_one_node)))
685     return gfc_trans_simple_do (code, &block, dovar, from, to, step);
686       
687   /* Initialize loop count. This code is executed before we enter the
688      loop body. We generate: count = (to + step - from) / step.  */
689
690   tmp = fold (build2 (MINUS_EXPR, type, step, from));
691   tmp = fold (build2 (PLUS_EXPR, type, to, tmp));
692   if (TREE_CODE (type) == INTEGER_TYPE)
693     {
694       tmp = fold (build2 (TRUNC_DIV_EXPR, type, tmp, step));
695       count = gfc_create_var (type, "count");
696     }
697   else
698     {
699       /* TODO: We could use the same width as the real type.
700          This would probably cause more problems that it solves
701          when we implement "long double" types.  */
702       tmp = fold (build2 (RDIV_EXPR, type, tmp, step));
703       tmp = fold (build1 (FIX_TRUNC_EXPR, gfc_array_index_type, tmp));
704       count = gfc_create_var (gfc_array_index_type, "count");
705     }
706   gfc_add_modify_expr (&block, count, tmp);
707
708   count_one = convert (TREE_TYPE (count), integer_one_node);
709
710   /* Initialize the DO variable: dovar = from.  */
711   gfc_add_modify_expr (&block, dovar, from);
712
713   /* Loop body.  */
714   gfc_start_block (&body);
715
716   /* Cycle and exit statements are implemented with gotos.  */
717   cycle_label = gfc_build_label_decl (NULL_TREE);
718   exit_label = gfc_build_label_decl (NULL_TREE);
719
720   /* Start with the loop condition.  Loop until count <= 0.  */
721   cond = build2 (LE_EXPR, boolean_type_node, count,
722                 convert (TREE_TYPE (count), integer_zero_node));
723   tmp = build1_v (GOTO_EXPR, exit_label);
724   TREE_USED (exit_label) = 1;
725   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
726   gfc_add_expr_to_block (&body, tmp);
727
728   /* Put these labels where they can be found later. We put the
729      labels in a TREE_LIST node (because TREE_CHAIN is already
730      used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
731      label in TREE_VALUE (backend_decl).  */
732
733   code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
734
735   /* Main loop body.  */
736   tmp = gfc_trans_code (code->block->next);
737   gfc_add_expr_to_block (&body, tmp);
738
739   /* Label for cycle statements (if needed).  */
740   if (TREE_USED (cycle_label))
741     {
742       tmp = build1_v (LABEL_EXPR, cycle_label);
743       gfc_add_expr_to_block (&body, tmp);
744     }
745
746   /* Increment the loop variable.  */
747   tmp = build2 (PLUS_EXPR, type, dovar, step);
748   gfc_add_modify_expr (&body, dovar, tmp);
749
750   /* Decrement the loop count.  */
751   tmp = build2 (MINUS_EXPR, TREE_TYPE (count), count, count_one);
752   gfc_add_modify_expr (&body, count, tmp);
753
754   /* End of loop body.  */
755   tmp = gfc_finish_block (&body);
756
757   /* The for loop itself.  */
758   tmp = build1_v (LOOP_EXPR, tmp);
759   gfc_add_expr_to_block (&block, tmp);
760
761   /* Add the exit label.  */
762   tmp = build1_v (LABEL_EXPR, exit_label);
763   gfc_add_expr_to_block (&block, tmp);
764
765   return gfc_finish_block (&block);
766 }
767
768
769 /* Translate the DO WHILE construct.
770
771    We translate
772
773    DO WHILE (cond)
774       body
775    END DO
776
777    to:
778
779    for ( ; ; )
780      {
781        pre_cond;
782        if (! cond) goto exit_label;
783        body;
784 cycle_label:
785      }
786 exit_label:
787
788    Because the evaluation of the exit condition `cond' may have side
789    effects, we can't do much for empty loop bodies.  The backend optimizers
790    should be smart enough to eliminate any dead loops.  */
791
792 tree
793 gfc_trans_do_while (gfc_code * code)
794 {
795   gfc_se cond;
796   tree tmp;
797   tree cycle_label;
798   tree exit_label;
799   stmtblock_t block;
800
801   /* Everything we build here is part of the loop body.  */
802   gfc_start_block (&block);
803
804   /* Cycle and exit statements are implemented with gotos.  */
805   cycle_label = gfc_build_label_decl (NULL_TREE);
806   exit_label = gfc_build_label_decl (NULL_TREE);
807
808   /* Put the labels where they can be found later. See gfc_trans_do().  */
809   code->block->backend_decl = tree_cons (cycle_label, exit_label, NULL);
810
811   /* Create a GIMPLE version of the exit condition.  */
812   gfc_init_se (&cond, NULL);
813   gfc_conv_expr_val (&cond, code->expr);
814   gfc_add_block_to_block (&block, &cond.pre);
815   cond.expr = fold (build1 (TRUTH_NOT_EXPR, boolean_type_node, cond.expr));
816
817   /* Build "IF (! cond) GOTO exit_label".  */
818   tmp = build1_v (GOTO_EXPR, exit_label);
819   TREE_USED (exit_label) = 1;
820   tmp = build3_v (COND_EXPR, cond.expr, tmp, build_empty_stmt ());
821   gfc_add_expr_to_block (&block, tmp);
822
823   /* The main body of the loop.  */
824   tmp = gfc_trans_code (code->block->next);
825   gfc_add_expr_to_block (&block, tmp);
826
827   /* Label for cycle statements (if needed).  */
828   if (TREE_USED (cycle_label))
829     {
830       tmp = build1_v (LABEL_EXPR, cycle_label);
831       gfc_add_expr_to_block (&block, tmp);
832     }
833
834   /* End of loop body.  */
835   tmp = gfc_finish_block (&block);
836
837   gfc_init_block (&block);
838   /* Build the loop.  */
839   tmp = build1_v (LOOP_EXPR, tmp);
840   gfc_add_expr_to_block (&block, tmp);
841
842   /* Add the exit label.  */
843   tmp = build1_v (LABEL_EXPR, exit_label);
844   gfc_add_expr_to_block (&block, tmp);
845
846   return gfc_finish_block (&block);
847 }
848
849
850 /* Translate the SELECT CASE construct for INTEGER case expressions,
851    without killing all potential optimizations.  The problem is that
852    Fortran allows unbounded cases, but the back-end does not, so we
853    need to intercept those before we enter the equivalent SWITCH_EXPR
854    we can build.
855
856    For example, we translate this,
857
858    SELECT CASE (expr)
859       CASE (:100,101,105:115)
860          block_1
861       CASE (190:199,200:)
862          block_2
863       CASE (300)
864          block_3
865       CASE DEFAULT
866          block_4
867    END SELECT
868
869    to the GENERIC equivalent,
870
871      switch (expr)
872        {
873          case (minimum value for typeof(expr) ... 100:
874          case 101:
875          case 105 ... 114:
876            block1:
877            goto end_label;
878
879          case 200 ... (maximum value for typeof(expr):
880          case 190 ... 199:
881            block2;
882            goto end_label;
883
884          case 300:
885            block_3;
886            goto end_label;
887
888          default:
889            block_4;
890            goto end_label;
891        }
892
893      end_label:  */
894
895 static tree
896 gfc_trans_integer_select (gfc_code * code)
897 {
898   gfc_code *c;
899   gfc_case *cp;
900   tree end_label;
901   tree tmp;
902   gfc_se se;
903   stmtblock_t block;
904   stmtblock_t body;
905
906   gfc_start_block (&block);
907
908   /* Calculate the switch expression.  */
909   gfc_init_se (&se, NULL);
910   gfc_conv_expr_val (&se, code->expr);
911   gfc_add_block_to_block (&block, &se.pre);
912
913   end_label = gfc_build_label_decl (NULL_TREE);
914
915   gfc_init_block (&body);
916
917   for (c = code->block; c; c = c->block)
918     {
919       for (cp = c->ext.case_list; cp; cp = cp->next)
920         {
921           tree low, high;
922           tree label;
923
924           /* Assume it's the default case.  */
925           low = high = NULL_TREE;
926
927           if (cp->low)
928             {
929               low = gfc_conv_constant_to_tree (cp->low);
930
931               /* If there's only a lower bound, set the high bound to the
932                  maximum value of the case expression.  */
933               if (!cp->high)
934                 high = TYPE_MAX_VALUE (TREE_TYPE (se.expr));
935             }
936
937           if (cp->high)
938             {
939               /* Three cases are possible here:
940
941                  1) There is no lower bound, e.g. CASE (:N).
942                  2) There is a lower bound .NE. high bound, that is
943                     a case range, e.g. CASE (N:M) where M>N (we make
944                     sure that M>N during type resolution).
945                  3) There is a lower bound, and it has the same value
946                     as the high bound, e.g. CASE (N:N).  This is our
947                     internal representation of CASE(N).
948
949                  In the first and second case, we need to set a value for
950                  high.  In the thirth case, we don't because the GCC middle
951                  end represents a single case value by just letting high be
952                  a NULL_TREE.  We can't do that because we need to be able
953                  to represent unbounded cases.  */
954
955               if (!cp->low
956                   || (cp->low
957                       && mpz_cmp (cp->low->value.integer,
958                                   cp->high->value.integer) != 0))
959                 high = gfc_conv_constant_to_tree (cp->high);
960
961               /* Unbounded case.  */
962               if (!cp->low)
963                 low = TYPE_MIN_VALUE (TREE_TYPE (se.expr));
964             }
965
966           /* Build a label.  */
967           label = gfc_build_label_decl (NULL_TREE);
968
969           /* Add this case label.
970              Add parameter 'label', make it match GCC backend.  */
971           tmp = build3 (CASE_LABEL_EXPR, void_type_node, low, high, label);
972           gfc_add_expr_to_block (&body, tmp);
973         }
974
975       /* Add the statements for this case.  */
976       tmp = gfc_trans_code (c->next);
977       gfc_add_expr_to_block (&body, tmp);
978
979       /* Break to the end of the construct.  */
980       tmp = build1_v (GOTO_EXPR, end_label);
981       gfc_add_expr_to_block (&body, tmp);
982     }
983
984   tmp = gfc_finish_block (&body);
985   tmp = build3_v (SWITCH_EXPR, se.expr, tmp, NULL_TREE);
986   gfc_add_expr_to_block (&block, tmp);
987
988   tmp = build1_v (LABEL_EXPR, end_label);
989   gfc_add_expr_to_block (&block, tmp);
990
991   return gfc_finish_block (&block);
992 }
993
994
995 /* Translate the SELECT CASE construct for LOGICAL case expressions.
996
997    There are only two cases possible here, even though the standard
998    does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
999    .FALSE., and DEFAULT.
1000
1001    We never generate more than two blocks here.  Instead, we always
1002    try to eliminate the DEFAULT case.  This way, we can translate this
1003    kind of SELECT construct to a simple
1004
1005    if {} else {};
1006
1007    expression in GENERIC.  */
1008
1009 static tree
1010 gfc_trans_logical_select (gfc_code * code)
1011 {
1012   gfc_code *c;
1013   gfc_code *t, *f, *d;
1014   gfc_case *cp;
1015   gfc_se se;
1016   stmtblock_t block;
1017
1018   /* Assume we don't have any cases at all.  */
1019   t = f = d = NULL;
1020
1021   /* Now see which ones we actually do have.  We can have at most two
1022      cases in a single case list: one for .TRUE. and one for .FALSE.
1023      The default case is always separate.  If the cases for .TRUE. and
1024      .FALSE. are in the same case list, the block for that case list
1025      always executed, and we don't generate code a COND_EXPR.  */
1026   for (c = code->block; c; c = c->block)
1027     {
1028       for (cp = c->ext.case_list; cp; cp = cp->next)
1029         {
1030           if (cp->low)
1031             {
1032               if (cp->low->value.logical == 0) /* .FALSE.  */
1033                 f = c;
1034               else /* if (cp->value.logical != 0), thus .TRUE.  */
1035                 t = c;
1036             }
1037           else
1038             d = c;
1039         }
1040     }
1041
1042   /* Start a new block.  */
1043   gfc_start_block (&block);
1044
1045   /* Calculate the switch expression.  We always need to do this
1046      because it may have side effects.  */
1047   gfc_init_se (&se, NULL);
1048   gfc_conv_expr_val (&se, code->expr);
1049   gfc_add_block_to_block (&block, &se.pre);
1050
1051   if (t == f && t != NULL)
1052     {
1053       /* Cases for .TRUE. and .FALSE. are in the same block.  Just
1054          translate the code for these cases, append it to the current
1055          block.  */
1056       gfc_add_expr_to_block (&block, gfc_trans_code (t->next));
1057     }
1058   else
1059     {
1060       tree true_tree, false_tree;
1061
1062       true_tree = build_empty_stmt ();
1063       false_tree = build_empty_stmt ();
1064
1065       /* If we have a case for .TRUE. and for .FALSE., discard the default case.
1066           Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
1067           make the missing case the default case.  */
1068       if (t != NULL && f != NULL)
1069         d = NULL;
1070       else if (d != NULL)
1071         {
1072           if (t == NULL)
1073             t = d;
1074           else
1075             f = d;
1076         }
1077
1078       /* Translate the code for each of these blocks, and append it to
1079          the current block.  */
1080       if (t != NULL)
1081         true_tree = gfc_trans_code (t->next);
1082
1083       if (f != NULL)
1084         false_tree = gfc_trans_code (f->next);
1085
1086       gfc_add_expr_to_block (&block, build3_v (COND_EXPR, se.expr,
1087                                                true_tree, false_tree));
1088     }
1089
1090   return gfc_finish_block (&block);
1091 }
1092
1093
1094 /* Translate the SELECT CASE construct for CHARACTER case expressions.
1095    Instead of generating compares and jumps, it is far simpler to
1096    generate a data structure describing the cases in order and call a
1097    library subroutine that locates the right case.
1098    This is particularly true because this is the only case where we
1099    might have to dispose of a temporary.
1100    The library subroutine returns a pointer to jump to or NULL if no
1101    branches are to be taken.  */
1102
1103 static tree
1104 gfc_trans_character_select (gfc_code *code)
1105 {
1106   tree init, node, end_label, tmp, type, args, *labels;
1107   stmtblock_t block, body;
1108   gfc_case *cp, *d;
1109   gfc_code *c;
1110   gfc_se se;
1111   int i, n;
1112
1113   static tree select_struct;
1114   static tree ss_string1, ss_string1_len;
1115   static tree ss_string2, ss_string2_len;
1116   static tree ss_target;
1117
1118   if (select_struct == NULL)
1119     {
1120       tree gfc_int4_type_node = gfc_get_int_type (4);
1121
1122       select_struct = make_node (RECORD_TYPE);
1123       TYPE_NAME (select_struct) = get_identifier ("_jump_struct");
1124
1125 #undef ADD_FIELD
1126 #define ADD_FIELD(NAME, TYPE)                           \
1127   ss_##NAME = gfc_add_field_to_struct                   \
1128      (&(TYPE_FIELDS (select_struct)), select_struct,    \
1129       get_identifier (stringize(NAME)), TYPE)
1130
1131       ADD_FIELD (string1, pchar_type_node);
1132       ADD_FIELD (string1_len, gfc_int4_type_node);
1133
1134       ADD_FIELD (string2, pchar_type_node);
1135       ADD_FIELD (string2_len, gfc_int4_type_node);
1136
1137       ADD_FIELD (target, pvoid_type_node);
1138 #undef ADD_FIELD
1139
1140       gfc_finish_type (select_struct);
1141     }
1142
1143   cp = code->block->ext.case_list;
1144   while (cp->left != NULL)
1145     cp = cp->left;
1146
1147   n = 0;
1148   for (d = cp; d; d = d->right)
1149     d->n = n++;
1150
1151   if (n != 0)
1152     labels = gfc_getmem (n * sizeof (tree));
1153   else
1154     labels = NULL;
1155
1156   for(i = 0; i < n; i++)
1157     {
1158       labels[i] = gfc_build_label_decl (NULL_TREE);
1159       TREE_USED (labels[i]) = 1;
1160       /* TODO: The gimplifier should do this for us, but it has
1161          inadequacies when dealing with static initializers.  */
1162       FORCED_LABEL (labels[i]) = 1;
1163     }
1164
1165   end_label = gfc_build_label_decl (NULL_TREE);
1166
1167   /* Generate the body */
1168   gfc_start_block (&block);
1169   gfc_init_block (&body);
1170
1171   for (c = code->block; c; c = c->block)
1172     {
1173       for (d = c->ext.case_list; d; d = d->next)
1174         {
1175           tmp = build1_v (LABEL_EXPR, labels[d->n]);
1176           gfc_add_expr_to_block (&body, tmp);
1177         }
1178
1179       tmp = gfc_trans_code (c->next);
1180       gfc_add_expr_to_block (&body, tmp);
1181
1182       tmp = build1_v (GOTO_EXPR, end_label);
1183       gfc_add_expr_to_block (&body, tmp);
1184     }
1185
1186   /* Generate the structure describing the branches */
1187   init = NULL_TREE;
1188   i = 0;
1189
1190   for(d = cp; d; d = d->right, i++)
1191     {
1192       node = NULL_TREE;
1193
1194       gfc_init_se (&se, NULL);
1195
1196       if (d->low == NULL)
1197         {
1198           node = tree_cons (ss_string1, null_pointer_node, node);
1199           node = tree_cons (ss_string1_len, integer_zero_node, node);
1200         }
1201       else
1202         {
1203           gfc_conv_expr_reference (&se, d->low);
1204
1205           node = tree_cons (ss_string1, se.expr, node);
1206           node = tree_cons (ss_string1_len, se.string_length, node);
1207         }
1208
1209       if (d->high == NULL)
1210         {
1211           node = tree_cons (ss_string2, null_pointer_node, node);
1212           node = tree_cons (ss_string2_len, integer_zero_node, node);
1213         }
1214       else
1215         {
1216           gfc_init_se (&se, NULL);
1217           gfc_conv_expr_reference (&se, d->high);
1218
1219           node = tree_cons (ss_string2, se.expr, node);
1220           node = tree_cons (ss_string2_len, se.string_length, node);
1221         }
1222
1223       tmp = gfc_build_addr_expr (pvoid_type_node, labels[i]);
1224       node = tree_cons (ss_target, tmp, node);
1225
1226       tmp = build1 (CONSTRUCTOR, select_struct, nreverse (node));
1227       init = tree_cons (NULL_TREE, tmp, init);
1228     }
1229
1230   type = build_array_type (select_struct, build_index_type
1231                            (build_int_cst (NULL_TREE, n - 1)));
1232
1233   init = build1 (CONSTRUCTOR, type, nreverse(init));
1234   TREE_CONSTANT (init) = 1;
1235   TREE_INVARIANT (init) = 1;
1236   TREE_STATIC (init) = 1;
1237   /* Create a static variable to hold the jump table.  */
1238   tmp = gfc_create_var (type, "jumptable");
1239   TREE_CONSTANT (tmp) = 1;
1240   TREE_INVARIANT (tmp) = 1;
1241   TREE_STATIC (tmp) = 1;
1242   DECL_INITIAL (tmp) = init;
1243   init = tmp;
1244
1245   /* Build an argument list for the library call */
1246   init = gfc_build_addr_expr (pvoid_type_node, init);
1247   args = gfc_chainon_list (NULL_TREE, init);
1248
1249   tmp = build_int_cst (NULL_TREE, n);
1250   args = gfc_chainon_list (args, tmp);
1251
1252   tmp = gfc_build_addr_expr (pvoid_type_node, end_label);
1253   args = gfc_chainon_list (args, tmp);
1254
1255   gfc_init_se (&se, NULL);
1256   gfc_conv_expr_reference (&se, code->expr);
1257
1258   args = gfc_chainon_list (args, se.expr);
1259   args = gfc_chainon_list (args, se.string_length);
1260
1261   gfc_add_block_to_block (&block, &se.pre);
1262
1263   tmp = gfc_build_function_call (gfor_fndecl_select_string, args);
1264   tmp = build1 (GOTO_EXPR, void_type_node, tmp);
1265   gfc_add_expr_to_block (&block, tmp);
1266
1267   tmp = gfc_finish_block (&body);
1268   gfc_add_expr_to_block (&block, tmp);
1269   tmp = build1_v (LABEL_EXPR, end_label);
1270   gfc_add_expr_to_block (&block, tmp);
1271
1272   if (n != 0)
1273     gfc_free (labels);
1274
1275   return gfc_finish_block (&block);
1276 }
1277
1278
1279 /* Translate the three variants of the SELECT CASE construct.
1280
1281    SELECT CASEs with INTEGER case expressions can be translated to an
1282    equivalent GENERIC switch statement, and for LOGICAL case
1283    expressions we build one or two if-else compares.
1284
1285    SELECT CASEs with CHARACTER case expressions are a whole different
1286    story, because they don't exist in GENERIC.  So we sort them and
1287    do a binary search at runtime.
1288
1289    Fortran has no BREAK statement, and it does not allow jumps from
1290    one case block to another.  That makes things a lot easier for
1291    the optimizers.  */
1292
1293 tree
1294 gfc_trans_select (gfc_code * code)
1295 {
1296   gcc_assert (code && code->expr);
1297
1298   /* Empty SELECT constructs are legal.  */
1299   if (code->block == NULL)
1300     return build_empty_stmt ();
1301
1302   /* Select the correct translation function.  */
1303   switch (code->expr->ts.type)
1304     {
1305     case BT_LOGICAL:    return gfc_trans_logical_select (code);
1306     case BT_INTEGER:    return gfc_trans_integer_select (code);
1307     case BT_CHARACTER:  return gfc_trans_character_select (code);
1308     default:
1309       gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
1310       /* Not reached */
1311     }
1312 }
1313
1314
1315 /* Generate the loops for a FORALL block.  The normal loop format:
1316     count = (end - start + step) / step
1317     loopvar = start
1318     while (1)
1319       {
1320         if (count <=0 )
1321           goto end_of_loop
1322         <body>
1323         loopvar += step
1324         count --
1325       }
1326     end_of_loop:  */
1327
1328 static tree
1329 gfc_trans_forall_loop (forall_info *forall_tmp, int nvar, tree body, int mask_flag)
1330 {
1331   int n;
1332   tree tmp;
1333   tree cond;
1334   stmtblock_t block;
1335   tree exit_label;
1336   tree count;
1337   tree var, start, end, step, mask, maskindex;
1338   iter_info *iter;
1339
1340   iter = forall_tmp->this_loop;
1341   for (n = 0; n < nvar; n++)
1342     {
1343       var = iter->var;
1344       start = iter->start;
1345       end = iter->end;
1346       step = iter->step;
1347
1348       exit_label = gfc_build_label_decl (NULL_TREE);
1349       TREE_USED (exit_label) = 1;
1350
1351       /* The loop counter.  */
1352       count = gfc_create_var (TREE_TYPE (var), "count");
1353
1354       /* The body of the loop.  */
1355       gfc_init_block (&block);
1356
1357       /* The exit condition.  */
1358       cond = build2 (LE_EXPR, boolean_type_node, count, integer_zero_node);
1359       tmp = build1_v (GOTO_EXPR, exit_label);
1360       tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1361       gfc_add_expr_to_block (&block, tmp);
1362
1363       /* The main loop body.  */
1364       gfc_add_expr_to_block (&block, body);
1365
1366       /* Increment the loop variable.  */
1367       tmp = build2 (PLUS_EXPR, TREE_TYPE (var), var, step);
1368       gfc_add_modify_expr (&block, var, tmp);
1369
1370       /* Advance to the next mask element.  */
1371       if (mask_flag)
1372         {
1373           mask = forall_tmp->mask;
1374           maskindex = forall_tmp->maskindex;
1375           if (mask)
1376             {
1377               tmp = build2 (PLUS_EXPR, gfc_array_index_type,
1378                             maskindex, gfc_index_one_node);
1379               gfc_add_modify_expr (&block, maskindex, tmp);
1380             }
1381         }
1382       /* Decrement the loop counter.  */
1383       tmp = build2 (MINUS_EXPR, TREE_TYPE (var), count, gfc_index_one_node);
1384       gfc_add_modify_expr (&block, count, tmp);
1385
1386       body = gfc_finish_block (&block);
1387
1388       /* Loop var initialization.  */
1389       gfc_init_block (&block);
1390       gfc_add_modify_expr (&block, var, start);
1391
1392       /* Initialize the loop counter.  */
1393       tmp = fold (build2 (MINUS_EXPR, TREE_TYPE (var), step, start));
1394       tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (var), end, tmp));
1395       tmp = fold (build2 (TRUNC_DIV_EXPR, TREE_TYPE (var), tmp, step));
1396       gfc_add_modify_expr (&block, count, tmp);
1397
1398       /* The loop expression.  */
1399       tmp = build1_v (LOOP_EXPR, body);
1400       gfc_add_expr_to_block (&block, tmp);
1401
1402       /* The exit label.  */
1403       tmp = build1_v (LABEL_EXPR, exit_label);
1404       gfc_add_expr_to_block (&block, tmp);
1405
1406       body = gfc_finish_block (&block);
1407       iter = iter->next;
1408     }
1409   return body;
1410 }
1411
1412
1413 /* Generate the body and loops according to MASK_FLAG and NEST_FLAG.
1414    if MASK_FLAG is nonzero, the body is controlled by maskes in forall
1415    nest, otherwise, the body is not controlled by maskes.
1416    if NEST_FLAG is nonzero, generate loops for nested forall, otherwise,
1417    only generate loops for the current forall level.  */
1418
1419 static tree
1420 gfc_trans_nested_forall_loop (forall_info * nested_forall_info, tree body,
1421                               int mask_flag, int nest_flag)
1422 {
1423   tree tmp;
1424   int nvar;
1425   forall_info *forall_tmp;
1426   tree pmask, mask, maskindex;
1427
1428   forall_tmp = nested_forall_info;
1429   /* Generate loops for nested forall.  */
1430   if (nest_flag)
1431     {
1432       while (forall_tmp->next_nest != NULL)
1433         forall_tmp = forall_tmp->next_nest;
1434       while (forall_tmp != NULL)
1435         {
1436           /* Generate body with masks' control.  */
1437           if (mask_flag)
1438             {
1439               pmask = forall_tmp->pmask;
1440               mask = forall_tmp->mask;
1441               maskindex = forall_tmp->maskindex;
1442
1443               if (mask)
1444                 {
1445                   /* If a mask was specified make the assignment conditional.  */
1446                   if (pmask)
1447                     tmp = gfc_build_indirect_ref (mask);
1448                   else
1449                     tmp = mask;
1450                   tmp = gfc_build_array_ref (tmp, maskindex);
1451
1452                   body = build3_v (COND_EXPR, tmp, body, build_empty_stmt ());
1453                 }
1454             }
1455           nvar = forall_tmp->nvar;
1456           body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1457           forall_tmp = forall_tmp->outer;
1458         }
1459     }
1460   else
1461     {
1462       nvar = forall_tmp->nvar;
1463       body = gfc_trans_forall_loop (forall_tmp, nvar, body, mask_flag);
1464     }
1465
1466   return body;
1467 }
1468
1469
1470 /* Allocate data for holding a temporary array.  Returns either a local
1471    temporary array or a pointer variable.  */
1472
1473 static tree
1474 gfc_do_allocate (tree bytesize, tree size, tree * pdata, stmtblock_t * pblock,
1475                  tree elem_type)
1476 {
1477   tree tmpvar;
1478   tree type;
1479   tree tmp;
1480   tree args;
1481
1482   if (INTEGER_CST_P (size))
1483     {
1484       tmp = fold (build2 (MINUS_EXPR, gfc_array_index_type, size,
1485                           gfc_index_one_node));
1486     }
1487   else
1488     tmp = NULL_TREE;
1489
1490   type = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
1491   type = build_array_type (elem_type, type);
1492   if (gfc_can_put_var_on_stack (bytesize))
1493     {
1494       gcc_assert (INTEGER_CST_P (size));
1495       tmpvar = gfc_create_var (type, "temp");
1496       *pdata = NULL_TREE;
1497     }
1498   else
1499     {
1500       tmpvar = gfc_create_var (build_pointer_type (type), "temp");
1501       *pdata = convert (pvoid_type_node, tmpvar);
1502
1503       args = gfc_chainon_list (NULL_TREE, bytesize);
1504       if (gfc_index_integer_kind == 4)
1505         tmp = gfor_fndecl_internal_malloc;
1506       else if (gfc_index_integer_kind == 8)
1507         tmp = gfor_fndecl_internal_malloc64;
1508       else
1509         gcc_unreachable ();
1510       tmp = gfc_build_function_call (tmp, args);
1511       tmp = convert (TREE_TYPE (tmpvar), tmp);
1512       gfc_add_modify_expr (pblock, tmpvar, tmp);
1513     }
1514   return tmpvar;
1515 }
1516
1517
1518 /* Generate codes to copy the temporary to the actual lhs.  */
1519
1520 static tree
1521 generate_loop_for_temp_to_lhs (gfc_expr *expr, tree tmp1, tree size,
1522                           tree count3, tree count1, tree count2, tree wheremask)
1523 {
1524   gfc_ss *lss;
1525   gfc_se lse, rse;
1526   stmtblock_t block, body;
1527   gfc_loopinfo loop1;
1528   tree tmp, tmp2;
1529   tree index;
1530   tree wheremaskexpr;
1531
1532   /* Walk the lhs.  */
1533   lss = gfc_walk_expr (expr);
1534
1535   if (lss == gfc_ss_terminator)
1536     {
1537       gfc_start_block (&block);
1538
1539       gfc_init_se (&lse, NULL);
1540
1541       /* Translate the expression.  */
1542       gfc_conv_expr (&lse, expr);
1543
1544       /* Form the expression for the temporary.  */
1545       tmp = gfc_build_array_ref (tmp1, count1);
1546
1547       /* Use the scalar assignment as is.  */
1548       gfc_add_block_to_block (&block, &lse.pre);
1549       gfc_add_modify_expr (&block, lse.expr, tmp);
1550       gfc_add_block_to_block (&block, &lse.post);
1551
1552       /* Increment the count1.  */
1553       tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (count1), count1, size));
1554       gfc_add_modify_expr (&block, count1, tmp);
1555       tmp = gfc_finish_block (&block);
1556     }
1557   else
1558     {
1559       gfc_start_block (&block);
1560
1561       gfc_init_loopinfo (&loop1);
1562       gfc_init_se (&rse, NULL);
1563       gfc_init_se (&lse, NULL);
1564
1565       /* Associate the lss with the loop.  */
1566       gfc_add_ss_to_loop (&loop1, lss);
1567
1568       /* Calculate the bounds of the scalarization.  */
1569       gfc_conv_ss_startstride (&loop1);
1570       /* Setup the scalarizing loops.  */
1571       gfc_conv_loop_setup (&loop1);
1572
1573       gfc_mark_ss_chain_used (lss, 1);
1574       /* Initialize count2.  */
1575       gfc_add_modify_expr (&block, count2, gfc_index_zero_node);
1576
1577       /* Start the scalarized loop body.  */
1578       gfc_start_scalarized_body (&loop1, &body);
1579
1580       /* Setup the gfc_se structures.  */
1581       gfc_copy_loopinfo_to_se (&lse, &loop1);
1582       lse.ss = lss;
1583
1584       /* Form the expression of the temporary.  */
1585       if (lss != gfc_ss_terminator)
1586         {
1587           index = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1588                                 count1, count2));
1589           rse.expr = gfc_build_array_ref (tmp1, index);
1590         }
1591       /* Translate expr.  */
1592       gfc_conv_expr (&lse, expr);
1593
1594       /* Use the scalar assignment.  */
1595       tmp = gfc_trans_scalar_assign (&lse, &rse, expr->ts.type);
1596
1597      /* Form the mask expression according to the mask tree list.  */
1598      if (wheremask)
1599        {
1600          wheremaskexpr = gfc_build_array_ref (wheremask, count3);
1601          tmp2 = TREE_CHAIN (wheremask);
1602          while (tmp2)
1603            {
1604              tmp1 = gfc_build_array_ref (tmp2, count3);
1605              wheremaskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
1606                                      wheremaskexpr, tmp1);
1607              tmp2 = TREE_CHAIN (tmp2);
1608            }
1609          tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1610        }
1611
1612       gfc_add_expr_to_block (&body, tmp);
1613
1614       /* Increment count2.  */
1615       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1616                           count2, gfc_index_one_node));
1617       gfc_add_modify_expr (&body, count2, tmp);
1618
1619       /* Increment count3.  */
1620       if (count3)
1621         {
1622           tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1623                               count3, gfc_index_one_node));
1624           gfc_add_modify_expr (&body, count3, tmp);
1625         }
1626
1627       /* Generate the copying loops.  */
1628       gfc_trans_scalarizing_loops (&loop1, &body);
1629       gfc_add_block_to_block (&block, &loop1.pre);
1630       gfc_add_block_to_block (&block, &loop1.post);
1631       gfc_cleanup_loop (&loop1);
1632
1633       /* Increment count1.  */
1634       tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (count1), count1, size));
1635       gfc_add_modify_expr (&block, count1, tmp);
1636       tmp = gfc_finish_block (&block);
1637     }
1638   return tmp;
1639 }
1640
1641
1642 /* Generate codes to copy rhs to the temporary. TMP1 is the address of temporary
1643    LSS and RSS are formed in function compute_inner_temp_size(), and should
1644    not be freed.  */
1645
1646 static tree
1647 generate_loop_for_rhs_to_temp (gfc_expr *expr2, tree tmp1, tree size,
1648                                tree count3, tree count1, tree count2,
1649                             gfc_ss *lss, gfc_ss *rss, tree wheremask)
1650 {
1651   stmtblock_t block, body1;
1652   gfc_loopinfo loop;
1653   gfc_se lse;
1654   gfc_se rse;
1655   tree tmp, tmp2, index;
1656   tree wheremaskexpr;
1657
1658   gfc_start_block (&block);
1659
1660   gfc_init_se (&rse, NULL);
1661   gfc_init_se (&lse, NULL);
1662
1663   if (lss == gfc_ss_terminator)
1664     {
1665       gfc_init_block (&body1);
1666       gfc_conv_expr (&rse, expr2);
1667       lse.expr = gfc_build_array_ref (tmp1, count1);
1668     }
1669   else
1670     {
1671       /* Initialize count2.  */
1672       gfc_add_modify_expr (&block, count2, gfc_index_zero_node);
1673
1674       /* Initialize the loop.  */
1675       gfc_init_loopinfo (&loop);
1676
1677       /* We may need LSS to determine the shape of the expression.  */
1678       gfc_add_ss_to_loop (&loop, lss);
1679       gfc_add_ss_to_loop (&loop, rss);
1680
1681       gfc_conv_ss_startstride (&loop);
1682       gfc_conv_loop_setup (&loop);
1683
1684       gfc_mark_ss_chain_used (rss, 1);
1685       /* Start the loop body.  */
1686       gfc_start_scalarized_body (&loop, &body1);
1687
1688       /* Translate the expression.  */
1689       gfc_copy_loopinfo_to_se (&rse, &loop);
1690       rse.ss = rss;
1691       gfc_conv_expr (&rse, expr2);
1692
1693       /* Form the expression of the temporary.  */
1694       index = fold (build2 (PLUS_EXPR, gfc_array_index_type, count1, count2));
1695       lse.expr = gfc_build_array_ref (tmp1, index);
1696     }
1697
1698   /* Use the scalar assignment.  */
1699   tmp = gfc_trans_scalar_assign (&lse, &rse, expr2->ts.type);
1700
1701   /* Form the mask expression according to the mask tree list.  */
1702   if (wheremask)
1703     {
1704       wheremaskexpr = gfc_build_array_ref (wheremask, count3);
1705       tmp2 = TREE_CHAIN (wheremask);
1706       while (tmp2)
1707         {
1708           tmp1 = gfc_build_array_ref (tmp2, count3);
1709           wheremaskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
1710                                   wheremaskexpr, tmp1);
1711           tmp2 = TREE_CHAIN (tmp2);
1712         }
1713       tmp = build3_v (COND_EXPR, wheremaskexpr, tmp, build_empty_stmt ());
1714     }
1715
1716   gfc_add_expr_to_block (&body1, tmp);
1717
1718   if (lss == gfc_ss_terminator)
1719     {
1720       gfc_add_block_to_block (&block, &body1);
1721     }
1722   else
1723     {
1724       /* Increment count2.  */
1725       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1726                           count2, gfc_index_one_node));
1727       gfc_add_modify_expr (&body1, count2, tmp);
1728
1729       /* Increment count3.  */
1730       if (count3)
1731         {
1732           tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1733                               count3, gfc_index_one_node));
1734           gfc_add_modify_expr (&body1, count3, tmp);
1735         }
1736
1737       /* Generate the copying loops.  */
1738       gfc_trans_scalarizing_loops (&loop, &body1);
1739
1740       gfc_add_block_to_block (&block, &loop.pre);
1741       gfc_add_block_to_block (&block, &loop.post);
1742
1743       gfc_cleanup_loop (&loop);
1744       /* TODO: Reuse lss and rss when copying temp->lhs.  Need to be careful
1745          as tree nodes in SS may not be valid in different scope.  */
1746     }
1747   /* Increment count1.  */
1748   tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (count1), count1, size));
1749   gfc_add_modify_expr (&block, count1, tmp);
1750
1751   tmp = gfc_finish_block (&block);
1752   return tmp;
1753 }
1754
1755
1756 /* Calculate the size of temporary needed in the assignment inside forall.
1757    LSS and RSS are filled in this function.  */
1758
1759 static tree
1760 compute_inner_temp_size (gfc_expr *expr1, gfc_expr *expr2,
1761                          stmtblock_t * pblock,
1762                          gfc_ss **lss, gfc_ss **rss)
1763 {
1764   gfc_loopinfo loop;
1765   tree size;
1766   int i;
1767   tree tmp;
1768
1769   *lss = gfc_walk_expr (expr1);
1770   *rss = NULL;
1771
1772   size = gfc_index_one_node;
1773   if (*lss != gfc_ss_terminator)
1774     {
1775       gfc_init_loopinfo (&loop);
1776
1777       /* Walk the RHS of the expression.  */
1778       *rss = gfc_walk_expr (expr2);
1779       if (*rss == gfc_ss_terminator)
1780         {
1781           /* The rhs is scalar.  Add a ss for the expression.  */
1782           *rss = gfc_get_ss ();
1783           (*rss)->next = gfc_ss_terminator;
1784           (*rss)->type = GFC_SS_SCALAR;
1785           (*rss)->expr = expr2;
1786         }
1787
1788       /* Associate the SS with the loop.  */
1789       gfc_add_ss_to_loop (&loop, *lss);
1790       /* We don't actually need to add the rhs at this point, but it might
1791          make guessing the loop bounds a bit easier.  */
1792       gfc_add_ss_to_loop (&loop, *rss);
1793
1794       /* We only want the shape of the expression, not rest of the junk
1795          generated by the scalarizer.  */
1796       loop.array_parameter = 1;
1797
1798       /* Calculate the bounds of the scalarization.  */
1799       gfc_conv_ss_startstride (&loop);
1800       gfc_conv_loop_setup (&loop);
1801
1802       /* Figure out how many elements we need.  */
1803       for (i = 0; i < loop.dimen; i++)
1804         {
1805           tmp = fold (build2 (MINUS_EXPR, gfc_array_index_type,
1806                               gfc_index_one_node, loop.from[i]));
1807           tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
1808                               tmp, loop.to[i]));
1809           size = fold (build2 (MULT_EXPR, gfc_array_index_type, size, tmp));
1810         }
1811       gfc_add_block_to_block (pblock, &loop.pre);
1812       size = gfc_evaluate_now (size, pblock);
1813       gfc_add_block_to_block (pblock, &loop.post);
1814
1815       /* TODO: write a function that cleans up a loopinfo without freeing
1816          the SS chains.  Currently a NOP.  */
1817     }
1818
1819   return size;
1820 }
1821
1822
1823 /* Calculate the overall iterator number of the nested forall construct.  */
1824
1825 static tree
1826 compute_overall_iter_number (forall_info *nested_forall_info, tree inner_size,
1827                              stmtblock_t *block)
1828 {
1829   tree tmp, number;
1830   stmtblock_t body;
1831
1832   /* TODO: optimizing the computing process.  */
1833   number = gfc_create_var (gfc_array_index_type, "num");
1834   gfc_add_modify_expr (block, number, gfc_index_zero_node);
1835
1836   gfc_start_block (&body);
1837   if (nested_forall_info)
1838     tmp = build2 (PLUS_EXPR, gfc_array_index_type, number,
1839                   inner_size);
1840   else
1841     tmp = inner_size;
1842   gfc_add_modify_expr (&body, number, tmp);
1843   tmp = gfc_finish_block (&body);
1844
1845   /* Generate loops.  */
1846   if (nested_forall_info != NULL)
1847     tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 0, 1);
1848
1849   gfc_add_expr_to_block (block, tmp);
1850
1851   return number;
1852 }
1853
1854
1855 /* Allocate temporary for forall construct according to the information in
1856    nested_forall_info.  INNER_SIZE is the size of temporary needed in the
1857    assignment inside forall.  PTEMP1 is returned for space free.  */
1858
1859 static tree
1860 allocate_temp_for_forall_nest (forall_info * nested_forall_info, tree type,
1861                                tree inner_size, stmtblock_t * block,
1862                                tree * ptemp1)
1863 {
1864   tree unit;
1865   tree temp1;
1866   tree tmp;
1867   tree bytesize, size;
1868
1869   /* Calculate the total size of temporary needed in forall construct.  */
1870   size = compute_overall_iter_number (nested_forall_info, inner_size, block);
1871
1872   unit = TYPE_SIZE_UNIT (type);
1873   bytesize = fold (build2 (MULT_EXPR, gfc_array_index_type, size, unit));
1874
1875   *ptemp1 = NULL;
1876   temp1 = gfc_do_allocate (bytesize, size, ptemp1, block, type);
1877
1878   if (*ptemp1)
1879     tmp = gfc_build_indirect_ref (temp1);
1880   else
1881     tmp = temp1;
1882
1883   return tmp;
1884 }
1885
1886
1887 /* Handle assignments inside forall which need temporary.  */
1888 static void
1889 gfc_trans_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2, tree wheremask,
1890                             forall_info * nested_forall_info,
1891                             stmtblock_t * block)
1892 {
1893   tree type;
1894   tree inner_size;
1895   gfc_ss *lss, *rss;
1896   tree count, count1, count2;
1897   tree tmp, tmp1;
1898   tree ptemp1;
1899   tree mask, maskindex;
1900   forall_info *forall_tmp;
1901
1902   /* Create vars. count1 is the current iterator number of the nested forall.
1903      count2 is the current iterator number of the inner loops needed in the
1904      assignment.  */
1905   count1 = gfc_create_var (gfc_array_index_type, "count1");
1906   count2 = gfc_create_var (gfc_array_index_type, "count2");
1907
1908   /* Count is the wheremask index.  */
1909   if (wheremask)
1910     {
1911       count = gfc_create_var (gfc_array_index_type, "count");
1912       gfc_add_modify_expr (block, count, gfc_index_zero_node);
1913     }
1914   else
1915     count = NULL;
1916
1917   /* Initialize count1.  */
1918   gfc_add_modify_expr (block, count1, gfc_index_zero_node);
1919
1920   /* Calculate the size of temporary needed in the assignment. Return loop, lss
1921      and rss which are used in function generate_loop_for_rhs_to_temp().  */
1922   inner_size = compute_inner_temp_size (expr1, expr2, block, &lss, &rss);
1923
1924   /* The type of LHS. Used in function allocate_temp_for_forall_nest */
1925   type = gfc_typenode_for_spec (&expr1->ts);
1926
1927   /* Allocate temporary for nested forall construct according to the
1928      information in nested_forall_info and inner_size.  */
1929   tmp1 = allocate_temp_for_forall_nest (nested_forall_info, type,
1930                                 inner_size, block, &ptemp1);
1931
1932   /* Initialize the maskindexes.  */
1933   forall_tmp = nested_forall_info;
1934   while (forall_tmp != NULL)
1935     {
1936       mask = forall_tmp->mask;
1937       maskindex = forall_tmp->maskindex;
1938       if (mask)
1939         gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
1940       forall_tmp = forall_tmp->next_nest;
1941     }
1942
1943   /* Generate codes to copy rhs to the temporary .  */
1944   tmp = generate_loop_for_rhs_to_temp (expr2, tmp1, inner_size, count,
1945                                        count1, count2, lss, rss, wheremask);
1946
1947   /* Generate body and loops according to the information in
1948      nested_forall_info.  */
1949   tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
1950   gfc_add_expr_to_block (block, tmp);
1951
1952   /* Reset count1.  */
1953   gfc_add_modify_expr (block, count1, gfc_index_zero_node);
1954
1955   /* Reset maskindexed.  */
1956   forall_tmp = nested_forall_info;
1957   while (forall_tmp != NULL)
1958     {
1959       mask = forall_tmp->mask;
1960       maskindex = forall_tmp->maskindex;
1961       if (mask)
1962         gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
1963       forall_tmp = forall_tmp->next_nest;
1964     }
1965
1966   /* Reset count.  */
1967   if (wheremask)
1968     gfc_add_modify_expr (block, count, gfc_index_zero_node);
1969
1970   /* Generate codes to copy the temporary to lhs.  */
1971   tmp = generate_loop_for_temp_to_lhs (expr1, tmp1, inner_size, count,
1972                                        count1, count2, wheremask);
1973
1974   /* Generate body and loops according to the information in
1975      nested_forall_info.  */
1976   tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
1977   gfc_add_expr_to_block (block, tmp);
1978
1979   if (ptemp1)
1980     {
1981       /* Free the temporary.  */
1982       tmp = gfc_chainon_list (NULL_TREE, ptemp1);
1983       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
1984       gfc_add_expr_to_block (block, tmp);
1985     }
1986 }
1987
1988
1989 /* Translate pointer assignment inside FORALL which need temporary.  */
1990
1991 static void
1992 gfc_trans_pointer_assign_need_temp (gfc_expr * expr1, gfc_expr * expr2,
1993                                     forall_info * nested_forall_info,
1994                                     stmtblock_t * block)
1995 {
1996   tree type;
1997   tree inner_size;
1998   gfc_ss *lss, *rss;
1999   gfc_se lse;
2000   gfc_se rse;
2001   gfc_ss_info *info;
2002   gfc_loopinfo loop;
2003   tree desc;
2004   tree parm;
2005   tree parmtype;
2006   stmtblock_t body;
2007   tree count;
2008   tree tmp, tmp1, ptemp1;
2009   tree mask, maskindex;
2010   forall_info *forall_tmp;
2011
2012   count = gfc_create_var (gfc_array_index_type, "count");
2013   gfc_add_modify_expr (block, count, gfc_index_zero_node);
2014
2015   inner_size = integer_one_node;
2016   lss = gfc_walk_expr (expr1);
2017   rss = gfc_walk_expr (expr2);
2018   if (lss == gfc_ss_terminator)
2019     {
2020       type = gfc_typenode_for_spec (&expr1->ts);
2021       type = build_pointer_type (type);
2022
2023       /* Allocate temporary for nested forall construct according to the
2024          information in nested_forall_info and inner_size.  */
2025       tmp1 = allocate_temp_for_forall_nest (nested_forall_info,
2026                                             type, inner_size, block, &ptemp1);
2027       gfc_start_block (&body);
2028       gfc_init_se (&lse, NULL);
2029       lse.expr = gfc_build_array_ref (tmp1, count);
2030       gfc_init_se (&rse, NULL);
2031       rse.want_pointer = 1;
2032       gfc_conv_expr (&rse, expr2);
2033       gfc_add_block_to_block (&body, &rse.pre);
2034       gfc_add_modify_expr (&body, lse.expr, rse.expr);
2035       gfc_add_block_to_block (&body, &rse.post);
2036
2037       /* Increment count.  */
2038       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2039                           count, gfc_index_one_node));
2040       gfc_add_modify_expr (&body, count, tmp);
2041
2042       tmp = gfc_finish_block (&body);
2043
2044       /* Initialize the maskindexes.  */
2045       forall_tmp = nested_forall_info;
2046       while (forall_tmp != NULL)
2047         {
2048           mask = forall_tmp->mask;
2049           maskindex = forall_tmp->maskindex;
2050           if (mask)
2051             gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2052           forall_tmp = forall_tmp->next_nest;
2053         }
2054
2055       /* Generate body and loops according to the information in
2056          nested_forall_info.  */
2057       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2058       gfc_add_expr_to_block (block, tmp);
2059
2060       /* Reset count.  */
2061       gfc_add_modify_expr (block, count, gfc_index_zero_node);
2062
2063       /* Reset maskindexes.  */
2064       forall_tmp = nested_forall_info;
2065       while (forall_tmp != NULL)
2066         {
2067           mask = forall_tmp->mask;
2068           maskindex = forall_tmp->maskindex;
2069           if (mask)
2070             gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2071           forall_tmp = forall_tmp->next_nest;
2072         }
2073       gfc_start_block (&body);
2074       gfc_init_se (&lse, NULL);
2075       gfc_init_se (&rse, NULL);
2076       rse.expr = gfc_build_array_ref (tmp1, count);
2077       lse.want_pointer = 1;
2078       gfc_conv_expr (&lse, expr1);
2079       gfc_add_block_to_block (&body, &lse.pre);
2080       gfc_add_modify_expr (&body, lse.expr, rse.expr);
2081       gfc_add_block_to_block (&body, &lse.post);
2082       /* Increment count.  */
2083       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2084                           count, gfc_index_one_node));
2085       gfc_add_modify_expr (&body, count, tmp);
2086       tmp = gfc_finish_block (&body);
2087
2088       /* Generate body and loops according to the information in
2089          nested_forall_info.  */
2090       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2091       gfc_add_expr_to_block (block, tmp);
2092     }
2093   else
2094     {
2095       gfc_init_loopinfo (&loop);
2096
2097       /* Associate the SS with the loop.  */
2098       gfc_add_ss_to_loop (&loop, rss);
2099
2100       /* Setup the scalarizing loops and bounds.  */
2101       gfc_conv_ss_startstride (&loop);
2102
2103       gfc_conv_loop_setup (&loop);
2104
2105       info = &rss->data.info;
2106       desc = info->descriptor;
2107
2108       /* Make a new descriptor.  */
2109       parmtype = gfc_get_element_type (TREE_TYPE (desc));
2110       parmtype = gfc_get_array_type_bounds (parmtype, loop.dimen,
2111                                             loop.from, loop.to, 1);
2112
2113       /* Allocate temporary for nested forall construct.  */
2114       tmp1 = allocate_temp_for_forall_nest (nested_forall_info, parmtype,
2115                                             inner_size, block, &ptemp1);
2116       gfc_start_block (&body);
2117       gfc_init_se (&lse, NULL);
2118       lse.expr = gfc_build_array_ref (tmp1, count);
2119       lse.direct_byref = 1;
2120       rss = gfc_walk_expr (expr2);
2121       gfc_conv_expr_descriptor (&lse, expr2, rss);
2122
2123       gfc_add_block_to_block (&body, &lse.pre);
2124       gfc_add_block_to_block (&body, &lse.post);
2125
2126       /* Increment count.  */
2127       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2128                           count, gfc_index_one_node));
2129       gfc_add_modify_expr (&body, count, tmp);
2130
2131       tmp = gfc_finish_block (&body);
2132
2133       /* Initialize the maskindexes.  */
2134       forall_tmp = nested_forall_info;
2135       while (forall_tmp != NULL)
2136         {
2137           mask = forall_tmp->mask;
2138           maskindex = forall_tmp->maskindex;
2139           if (mask)
2140             gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2141           forall_tmp = forall_tmp->next_nest;
2142         }
2143
2144       /* Generate body and loops according to the information in
2145          nested_forall_info.  */
2146       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2147       gfc_add_expr_to_block (block, tmp);
2148
2149       /* Reset count.  */
2150       gfc_add_modify_expr (block, count, gfc_index_zero_node);
2151
2152       /* Reset maskindexes.  */
2153       forall_tmp = nested_forall_info;
2154       while (forall_tmp != NULL)
2155         {
2156           mask = forall_tmp->mask;
2157           maskindex = forall_tmp->maskindex;
2158           if (mask)
2159             gfc_add_modify_expr (block, maskindex, gfc_index_zero_node);
2160           forall_tmp = forall_tmp->next_nest;
2161         }
2162       parm = gfc_build_array_ref (tmp1, count);
2163       lss = gfc_walk_expr (expr1);
2164       gfc_init_se (&lse, NULL);
2165       gfc_conv_expr_descriptor (&lse, expr1, lss);
2166       gfc_add_modify_expr (&lse.pre, lse.expr, parm);
2167       gfc_start_block (&body);
2168       gfc_add_block_to_block (&body, &lse.pre);
2169       gfc_add_block_to_block (&body, &lse.post);
2170
2171       /* Increment count.  */
2172       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2173                           count, gfc_index_one_node));
2174       gfc_add_modify_expr (&body, count, tmp);
2175
2176       tmp = gfc_finish_block (&body);
2177
2178       tmp = gfc_trans_nested_forall_loop (nested_forall_info, tmp, 1, 1);
2179       gfc_add_expr_to_block (block, tmp);
2180     }
2181   /* Free the temporary.  */
2182   if (ptemp1)
2183     {
2184       tmp = gfc_chainon_list (NULL_TREE, ptemp1);
2185       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2186       gfc_add_expr_to_block (block, tmp);
2187     }
2188 }
2189
2190
2191 /* FORALL and WHERE statements are really nasty, especially when you nest
2192    them. All the rhs of a forall assignment must be evaluated before the
2193    actual assignments are performed. Presumably this also applies to all the
2194    assignments in an inner where statement.  */
2195
2196 /* Generate code for a FORALL statement.  Any temporaries are allocated as a
2197    linear array, relying on the fact that we process in the same order in all
2198    loops.
2199
2200     forall (i=start:end:stride; maskexpr)
2201       e<i> = f<i>
2202       g<i> = h<i>
2203     end forall
2204    (where e,f,g,h<i> are arbitrary expressions possibly involving i)
2205    Translates to:
2206     count = ((end + 1 - start) / staride)
2207     masktmp(:) = maskexpr(:)
2208
2209     maskindex = 0;
2210     for (i = start; i <= end; i += stride)
2211       {
2212         if (masktmp[maskindex++])
2213           e<i> = f<i>
2214       }
2215     maskindex = 0;
2216     for (i = start; i <= end; i += stride)
2217       {
2218         if (masktmp[maskindex++])
2219           e<i> = f<i>
2220       }
2221
2222     Note that this code only works when there are no dependencies.
2223     Forall loop with array assignments and data dependencies are a real pain,
2224     because the size of the temporary cannot always be determined before the
2225     loop is executed.  This problem is compounded by the presence of nested
2226     FORALL constructs.
2227  */
2228
2229 static tree
2230 gfc_trans_forall_1 (gfc_code * code, forall_info * nested_forall_info)
2231 {
2232   stmtblock_t block;
2233   stmtblock_t body;
2234   tree *var;
2235   tree *start;
2236   tree *end;
2237   tree *step;
2238   gfc_expr **varexpr;
2239   tree tmp;
2240   tree assign;
2241   tree size;
2242   tree bytesize;
2243   tree tmpvar;
2244   tree sizevar;
2245   tree lenvar;
2246   tree maskindex;
2247   tree mask;
2248   tree pmask;
2249   int n;
2250   int nvar;
2251   int need_temp;
2252   gfc_forall_iterator *fa;
2253   gfc_se se;
2254   gfc_code *c;
2255   gfc_saved_var *saved_vars;
2256   iter_info *this_forall, *iter_tmp;
2257   forall_info *info, *forall_tmp;
2258   temporary_list *temp;
2259
2260   gfc_start_block (&block);
2261
2262   n = 0;
2263   /* Count the FORALL index number.  */
2264   for (fa = code->ext.forall_iterator; fa; fa = fa->next)
2265     n++;
2266   nvar = n;
2267
2268   /* Allocate the space for var, start, end, step, varexpr.  */
2269   var = (tree *) gfc_getmem (nvar * sizeof (tree));
2270   start = (tree *) gfc_getmem (nvar * sizeof (tree));
2271   end = (tree *) gfc_getmem (nvar * sizeof (tree));
2272   step = (tree *) gfc_getmem (nvar * sizeof (tree));
2273   varexpr = (gfc_expr **) gfc_getmem (nvar * sizeof (gfc_expr *));
2274   saved_vars = (gfc_saved_var *) gfc_getmem (nvar * sizeof (gfc_saved_var));
2275
2276   /* Allocate the space for info.  */
2277   info = (forall_info *) gfc_getmem (sizeof (forall_info));
2278   n = 0;
2279   for (fa = code->ext.forall_iterator; fa; fa = fa->next)
2280     {
2281       gfc_symbol *sym = fa->var->symtree->n.sym;
2282
2283       /* allocate space for this_forall.  */
2284       this_forall = (iter_info *) gfc_getmem (sizeof (iter_info));
2285
2286       /* Create a temporary variable for the FORALL index.  */
2287       tmp = gfc_typenode_for_spec (&sym->ts);
2288       var[n] = gfc_create_var (tmp, sym->name);
2289       gfc_shadow_sym (sym, var[n], &saved_vars[n]);
2290
2291       /* Record it in this_forall.  */
2292       this_forall->var = var[n];
2293
2294       /* Replace the index symbol's backend_decl with the temporary decl.  */
2295       sym->backend_decl = var[n];
2296
2297       /* Work out the start, end and stride for the loop.  */
2298       gfc_init_se (&se, NULL);
2299       gfc_conv_expr_val (&se, fa->start);
2300       /* Record it in this_forall.  */
2301       this_forall->start = se.expr;
2302       gfc_add_block_to_block (&block, &se.pre);
2303       start[n] = se.expr;
2304
2305       gfc_init_se (&se, NULL);
2306       gfc_conv_expr_val (&se, fa->end);
2307       /* Record it in this_forall.  */
2308       this_forall->end = se.expr;
2309       gfc_make_safe_expr (&se);
2310       gfc_add_block_to_block (&block, &se.pre);
2311       end[n] = se.expr;
2312
2313       gfc_init_se (&se, NULL);
2314       gfc_conv_expr_val (&se, fa->stride);
2315       /* Record it in this_forall.  */
2316       this_forall->step = se.expr;
2317       gfc_make_safe_expr (&se);
2318       gfc_add_block_to_block (&block, &se.pre);
2319       step[n] = se.expr;
2320
2321       /* Set the NEXT field of this_forall to NULL.  */
2322       this_forall->next = NULL;
2323       /* Link this_forall to the info construct.  */
2324       if (info->this_loop == NULL)
2325         info->this_loop = this_forall;
2326       else
2327         {
2328           iter_tmp = info->this_loop;
2329           while (iter_tmp->next != NULL)
2330             iter_tmp = iter_tmp->next;
2331           iter_tmp->next = this_forall;
2332         }
2333
2334       n++;
2335     }
2336   nvar = n;
2337
2338   /* Work out the number of elements in the mask array.  */
2339   tmpvar = NULL_TREE;
2340   lenvar = NULL_TREE;
2341   size = gfc_index_one_node;
2342   sizevar = NULL_TREE;
2343
2344   for (n = 0; n < nvar; n++)
2345     {
2346       if (lenvar && TREE_TYPE (lenvar) != TREE_TYPE (start[n]))
2347         lenvar = NULL_TREE;
2348
2349       /* size = (end + step - start) / step.  */
2350       tmp = fold (build2 (MINUS_EXPR, TREE_TYPE (start[n]), 
2351                           step[n], start[n]));
2352       tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (end[n]), end[n], tmp));
2353
2354       tmp = fold (build2 (FLOOR_DIV_EXPR, TREE_TYPE (tmp), tmp, step[n]));
2355       tmp = convert (gfc_array_index_type, tmp);
2356
2357       size = fold (build2 (MULT_EXPR, gfc_array_index_type, size, tmp));
2358     }
2359
2360   /* Record the nvar and size of current forall level.  */
2361   info->nvar = nvar;
2362   info->size = size;
2363
2364   /* Link the current forall level to nested_forall_info.  */
2365   forall_tmp = nested_forall_info;
2366   if (forall_tmp == NULL)
2367     nested_forall_info = info;
2368   else
2369     {
2370       while (forall_tmp->next_nest != NULL)
2371         forall_tmp = forall_tmp->next_nest;
2372       info->outer = forall_tmp;
2373       forall_tmp->next_nest = info;
2374     }
2375
2376   /* Copy the mask into a temporary variable if required.
2377      For now we assume a mask temporary is needed.  */
2378   if (code->expr)
2379     {
2380       /* Allocate the mask temporary.  */
2381       bytesize = fold (build2 (MULT_EXPR, gfc_array_index_type, size,
2382                                TYPE_SIZE_UNIT (boolean_type_node)));
2383
2384       mask = gfc_do_allocate (bytesize, size, &pmask, &block, boolean_type_node);
2385
2386       maskindex = gfc_create_var_np (gfc_array_index_type, "mi");
2387       /* Record them in the info structure.  */
2388       info->pmask = pmask;
2389       info->mask = mask;
2390       info->maskindex = maskindex;
2391
2392       gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2393
2394       /* Start of mask assignment loop body.  */
2395       gfc_start_block (&body);
2396
2397       /* Evaluate the mask expression.  */
2398       gfc_init_se (&se, NULL);
2399       gfc_conv_expr_val (&se, code->expr);
2400       gfc_add_block_to_block (&body, &se.pre);
2401
2402       /* Store the mask.  */
2403       se.expr = convert (boolean_type_node, se.expr);
2404
2405       if (pmask)
2406         tmp = gfc_build_indirect_ref (mask);
2407       else
2408         tmp = mask;
2409       tmp = gfc_build_array_ref (tmp, maskindex);
2410       gfc_add_modify_expr (&body, tmp, se.expr);
2411
2412       /* Advance to the next mask element.  */
2413       tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2414                    maskindex, gfc_index_one_node);
2415       gfc_add_modify_expr (&body, maskindex, tmp);
2416
2417       /* Generate the loops.  */
2418       tmp = gfc_finish_block (&body);
2419       tmp = gfc_trans_nested_forall_loop (info, tmp, 0, 0);
2420       gfc_add_expr_to_block (&block, tmp);
2421     }
2422   else
2423     {
2424       /* No mask was specified.  */
2425       maskindex = NULL_TREE;
2426       mask = pmask = NULL_TREE;
2427     }
2428
2429   c = code->block->next;
2430
2431   /* TODO: loop merging in FORALL statements.  */
2432   /* Now that we've got a copy of the mask, generate the assignment loops.  */
2433   while (c)
2434     {
2435       switch (c->op)
2436         {
2437         case EXEC_ASSIGN:
2438           /* A scalar or array assignment.  */
2439           need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
2440           /* Teporaries due to array assignment data dependencies introduce
2441              no end of problems.  */
2442           if (need_temp)
2443             gfc_trans_assign_need_temp (c->expr, c->expr2, NULL,
2444                                         nested_forall_info, &block);
2445           else
2446             {
2447               /* Use the normal assignment copying routines.  */
2448               assign = gfc_trans_assignment (c->expr, c->expr2);
2449
2450               /* Reset the mask index.  */
2451               if (mask)
2452                 gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2453
2454               /* Generate body and loops.  */
2455               tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign, 1, 1);
2456               gfc_add_expr_to_block (&block, tmp);
2457             }
2458
2459           break;
2460
2461         case EXEC_WHERE:
2462
2463           /* Translate WHERE or WHERE construct nested in FORALL.  */
2464           temp = NULL;
2465           gfc_trans_where_2 (c, NULL, NULL, nested_forall_info, &block, &temp);
2466
2467           while (temp)
2468             {
2469               tree args;
2470               temporary_list *p;
2471
2472               /* Free the temporary.  */
2473               args = gfc_chainon_list (NULL_TREE, temp->temporary);
2474               tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
2475               gfc_add_expr_to_block (&block, tmp);
2476
2477               p = temp;
2478               temp = temp->next;
2479               gfc_free (p);
2480             }
2481
2482           break;
2483
2484         /* Pointer assignment inside FORALL.  */
2485         case EXEC_POINTER_ASSIGN:
2486           need_temp = gfc_check_dependency (c->expr, c->expr2, varexpr, nvar);
2487           if (need_temp)
2488             gfc_trans_pointer_assign_need_temp (c->expr, c->expr2,
2489                                                 nested_forall_info, &block);
2490           else
2491             {
2492               /* Use the normal assignment copying routines.  */
2493               assign = gfc_trans_pointer_assignment (c->expr, c->expr2);
2494
2495               /* Reset the mask index.  */
2496               if (mask)
2497                 gfc_add_modify_expr (&block, maskindex, gfc_index_zero_node);
2498
2499               /* Generate body and loops.  */
2500               tmp = gfc_trans_nested_forall_loop (nested_forall_info, assign,
2501                                                   1, 1);
2502               gfc_add_expr_to_block (&block, tmp);
2503             }
2504           break;
2505
2506         case EXEC_FORALL:
2507           tmp = gfc_trans_forall_1 (c, nested_forall_info);
2508           gfc_add_expr_to_block (&block, tmp);
2509           break;
2510
2511         default:
2512           gcc_unreachable ();
2513         }
2514
2515       c = c->next;
2516     }
2517
2518   /* Restore the original index variables.  */
2519   for (fa = code->ext.forall_iterator, n = 0; fa; fa = fa->next, n++)
2520     gfc_restore_sym (fa->var->symtree->n.sym, &saved_vars[n]);
2521
2522   /* Free the space for var, start, end, step, varexpr.  */
2523   gfc_free (var);
2524   gfc_free (start);
2525   gfc_free (end);
2526   gfc_free (step);
2527   gfc_free (varexpr);
2528   gfc_free (saved_vars);
2529
2530   if (pmask)
2531     {
2532       /* Free the temporary for the mask.  */
2533       tmp = gfc_chainon_list (NULL_TREE, pmask);
2534       tmp = gfc_build_function_call (gfor_fndecl_internal_free, tmp);
2535       gfc_add_expr_to_block (&block, tmp);
2536     }
2537   if (maskindex)
2538     pushdecl (maskindex);
2539
2540   return gfc_finish_block (&block);
2541 }
2542
2543
2544 /* Translate the FORALL statement or construct.  */
2545
2546 tree gfc_trans_forall (gfc_code * code)
2547 {
2548   return gfc_trans_forall_1 (code, NULL);
2549 }
2550
2551
2552 /* Evaluate the WHERE mask expression, copy its value to a temporary.
2553    If the WHERE construct is nested in FORALL, compute the overall temporary
2554    needed by the WHERE mask expression multiplied by the iterator number of
2555    the nested forall.
2556    ME is the WHERE mask expression.
2557    MASK is the temporary which value is mask's value.
2558    NMASK is another temporary which value is !mask.
2559    TEMP records the temporary's address allocated in this function in order to
2560    free them outside this function.
2561    MASK, NMASK and TEMP are all OUT arguments.  */
2562
2563 static tree
2564 gfc_evaluate_where_mask (gfc_expr * me, forall_info * nested_forall_info,
2565                          tree * mask, tree * nmask, temporary_list ** temp,
2566                          stmtblock_t * block)
2567 {
2568   tree tmp, tmp1;
2569   gfc_ss *lss, *rss;
2570   gfc_loopinfo loop;
2571   tree ptemp1, ntmp, ptemp2;
2572   tree inner_size;
2573   stmtblock_t body, body1;
2574   gfc_se lse, rse;
2575   tree count;
2576   tree tmpexpr;
2577
2578   gfc_init_loopinfo (&loop);
2579
2580   /* Calculate the size of temporary needed by the mask-expr.  */
2581   inner_size = compute_inner_temp_size (me, me, block, &lss, &rss);
2582
2583   /* Allocate temporary for where mask.  */
2584   tmp = allocate_temp_for_forall_nest (nested_forall_info, boolean_type_node,
2585                                        inner_size, block, &ptemp1);
2586   /* Record the temporary address in order to free it later.  */
2587   if (ptemp1)
2588     {
2589       temporary_list *tempo;
2590       tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2591       tempo->temporary = ptemp1;
2592       tempo->next = *temp;
2593       *temp = tempo;
2594     }
2595
2596   /* Allocate temporary for !mask.  */
2597   ntmp = allocate_temp_for_forall_nest (nested_forall_info, boolean_type_node,
2598                                         inner_size, block, &ptemp2);
2599   /* Record the temporary  in order to free it later.  */
2600   if (ptemp2)
2601     {
2602       temporary_list *tempo;
2603       tempo = (temporary_list *) gfc_getmem (sizeof (temporary_list));
2604       tempo->temporary = ptemp2;
2605       tempo->next = *temp;
2606       *temp = tempo;
2607     }
2608
2609   /* Variable to index the temporary.  */
2610   count = gfc_create_var (gfc_array_index_type, "count");
2611   /* Initialize count.  */
2612   gfc_add_modify_expr (block, count, gfc_index_zero_node);
2613
2614   gfc_start_block (&body);
2615
2616   gfc_init_se (&rse, NULL);
2617   gfc_init_se (&lse, NULL);
2618
2619   if (lss == gfc_ss_terminator)
2620     {
2621       gfc_init_block (&body1);
2622     }
2623   else
2624     {
2625       /* Initialize the loop.  */
2626       gfc_init_loopinfo (&loop);
2627
2628       /* We may need LSS to determine the shape of the expression.  */
2629       gfc_add_ss_to_loop (&loop, lss);
2630       gfc_add_ss_to_loop (&loop, rss);
2631
2632       gfc_conv_ss_startstride (&loop);
2633       gfc_conv_loop_setup (&loop);
2634
2635       gfc_mark_ss_chain_used (rss, 1);
2636       /* Start the loop body.  */
2637       gfc_start_scalarized_body (&loop, &body1);
2638
2639       /* Translate the expression.  */
2640       gfc_copy_loopinfo_to_se (&rse, &loop);
2641       rse.ss = rss;
2642       gfc_conv_expr (&rse, me);
2643     }
2644   /* Form the expression of the temporary.  */
2645   lse.expr = gfc_build_array_ref (tmp, count);
2646   tmpexpr = gfc_build_array_ref (ntmp, count);
2647
2648   /* Use the scalar assignment to fill temporary TMP.  */
2649   tmp1 = gfc_trans_scalar_assign (&lse, &rse, me->ts.type);
2650   gfc_add_expr_to_block (&body1, tmp1);
2651
2652   /* Fill temporary NTMP.  */
2653   tmp1 = build1 (TRUTH_NOT_EXPR, TREE_TYPE (lse.expr), lse.expr);
2654   gfc_add_modify_expr (&body1, tmpexpr, tmp1);
2655
2656  if (lss == gfc_ss_terminator)
2657     {
2658       gfc_add_block_to_block (&body, &body1);
2659     }
2660   else
2661     {
2662       /* Increment count.  */
2663       tmp1 = fold (build2 (PLUS_EXPR, gfc_array_index_type, count,
2664                           gfc_index_one_node));
2665       gfc_add_modify_expr (&body1, count, tmp1);
2666
2667       /* Generate the copying loops.  */
2668       gfc_trans_scalarizing_loops (&loop, &body1);
2669
2670       gfc_add_block_to_block (&body, &loop.pre);
2671       gfc_add_block_to_block (&body, &loop.post);
2672
2673       gfc_cleanup_loop (&loop);
2674       /* TODO: Reuse lss and rss when copying temp->lhs.  Need to be careful
2675          as tree nodes in SS may not be valid in different scope.  */
2676     }
2677
2678   tmp1 = gfc_finish_block (&body);
2679   /* If the WHERE construct is inside FORALL, fill the full temporary.  */
2680   if (nested_forall_info != NULL)
2681     tmp1 = gfc_trans_nested_forall_loop (nested_forall_info, tmp1, 1, 1);
2682
2683
2684   gfc_add_expr_to_block (block, tmp1);
2685
2686   *mask = tmp;
2687   *nmask = ntmp;
2688
2689   return tmp1;
2690 }
2691
2692
2693 /* Translate an assignment statement in a WHERE statement or construct
2694    statement. The MASK expression is used to control which elements
2695    of EXPR1 shall be assigned.  */
2696
2697 static tree
2698 gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2, tree mask,
2699                         tree count1, tree count2)
2700 {
2701   gfc_se lse;
2702   gfc_se rse;
2703   gfc_ss *lss;
2704   gfc_ss *lss_section;
2705   gfc_ss *rss;
2706
2707   gfc_loopinfo loop;
2708   tree tmp;
2709   stmtblock_t block;
2710   stmtblock_t body;
2711   tree index, maskexpr, tmp1;
2712
2713 #if 0
2714   /* TODO: handle this special case.
2715      Special case a single function returning an array.  */
2716   if (expr2->expr_type == EXPR_FUNCTION && expr2->rank > 0)
2717     {
2718       tmp = gfc_trans_arrayfunc_assign (expr1, expr2);
2719       if (tmp)
2720         return tmp;
2721     }
2722 #endif
2723
2724  /* Assignment of the form lhs = rhs.  */
2725   gfc_start_block (&block);
2726
2727   gfc_init_se (&lse, NULL);
2728   gfc_init_se (&rse, NULL);
2729
2730   /* Walk the lhs.  */
2731   lss = gfc_walk_expr (expr1);
2732   rss = NULL;
2733
2734   /* In each where-assign-stmt, the mask-expr and the variable being
2735      defined shall be arrays of the same shape.  */
2736   gcc_assert (lss != gfc_ss_terminator);
2737
2738   /* The assignment needs scalarization.  */
2739   lss_section = lss;
2740
2741   /* Find a non-scalar SS from the lhs.  */
2742   while (lss_section != gfc_ss_terminator
2743          && lss_section->type != GFC_SS_SECTION)
2744     lss_section = lss_section->next;
2745
2746   gcc_assert (lss_section != gfc_ss_terminator);
2747
2748   /* Initialize the scalarizer.  */
2749   gfc_init_loopinfo (&loop);
2750
2751   /* Walk the rhs.  */
2752   rss = gfc_walk_expr (expr2);
2753   if (rss == gfc_ss_terminator)
2754    {
2755      /* The rhs is scalar.  Add a ss for the expression.  */
2756      rss = gfc_get_ss ();
2757      rss->next = gfc_ss_terminator;
2758      rss->type = GFC_SS_SCALAR;
2759      rss->expr = expr2;
2760     }
2761
2762   /* Associate the SS with the loop.  */
2763   gfc_add_ss_to_loop (&loop, lss);
2764   gfc_add_ss_to_loop (&loop, rss);
2765
2766   /* Calculate the bounds of the scalarization.  */
2767   gfc_conv_ss_startstride (&loop);
2768
2769   /* Resolve any data dependencies in the statement.  */
2770   gfc_conv_resolve_dependencies (&loop, lss_section, rss);
2771
2772   /* Setup the scalarizing loops.  */
2773   gfc_conv_loop_setup (&loop);
2774
2775   /* Setup the gfc_se structures.  */
2776   gfc_copy_loopinfo_to_se (&lse, &loop);
2777   gfc_copy_loopinfo_to_se (&rse, &loop);
2778
2779   rse.ss = rss;
2780   gfc_mark_ss_chain_used (rss, 1);
2781   if (loop.temp_ss == NULL)
2782     {
2783       lse.ss = lss;
2784       gfc_mark_ss_chain_used (lss, 1);
2785     }
2786   else
2787     {
2788       lse.ss = loop.temp_ss;
2789       gfc_mark_ss_chain_used (lss, 3);
2790       gfc_mark_ss_chain_used (loop.temp_ss, 3);
2791     }
2792
2793   /* Start the scalarized loop body.  */
2794   gfc_start_scalarized_body (&loop, &body);
2795
2796   /* Translate the expression.  */
2797   gfc_conv_expr (&rse, expr2);
2798   if (lss != gfc_ss_terminator && loop.temp_ss != NULL)
2799     {
2800       gfc_conv_tmp_array_ref (&lse);
2801       gfc_advance_se_ss_chain (&lse);
2802     }
2803   else
2804     gfc_conv_expr (&lse, expr1);
2805
2806   /* Form the mask expression according to the mask tree list.  */
2807   index = count1;
2808   tmp = mask;
2809   if (tmp != NULL)
2810     maskexpr = gfc_build_array_ref (tmp, index);
2811   else
2812     maskexpr = NULL;
2813
2814   tmp = TREE_CHAIN (tmp);
2815   while (tmp)
2816     {
2817       tmp1 = gfc_build_array_ref (tmp, index);
2818       maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1), maskexpr, tmp1);
2819       tmp = TREE_CHAIN (tmp);
2820     }
2821   /* Use the scalar assignment as is.  */
2822   tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2823   tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
2824
2825   gfc_add_expr_to_block (&body, tmp);
2826
2827   if (lss == gfc_ss_terminator)
2828     {
2829       /* Increment count1.  */
2830       tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2831                           count1, gfc_index_one_node));
2832       gfc_add_modify_expr (&body, count1, tmp);
2833
2834       /* Use the scalar assignment as is.  */
2835       gfc_add_block_to_block (&block, &body);
2836     }
2837   else
2838     {
2839       gcc_assert (lse.ss == gfc_ss_terminator
2840                   && rse.ss == gfc_ss_terminator);
2841
2842       if (loop.temp_ss != NULL)
2843         {
2844           /* Increment count1 before finish the main body of a scalarized
2845              expression.  */
2846           tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2847                               count1, gfc_index_one_node));
2848           gfc_add_modify_expr (&body, count1, tmp);
2849           gfc_trans_scalarized_loop_boundary (&loop, &body);
2850
2851           /* We need to copy the temporary to the actual lhs.  */
2852           gfc_init_se (&lse, NULL);
2853           gfc_init_se (&rse, NULL);
2854           gfc_copy_loopinfo_to_se (&lse, &loop);
2855           gfc_copy_loopinfo_to_se (&rse, &loop);
2856
2857           rse.ss = loop.temp_ss;
2858           lse.ss = lss;
2859
2860           gfc_conv_tmp_array_ref (&rse);
2861           gfc_advance_se_ss_chain (&rse);
2862           gfc_conv_expr (&lse, expr1);
2863
2864           gcc_assert (lse.ss == gfc_ss_terminator
2865                       && rse.ss == gfc_ss_terminator);
2866
2867           /* Form the mask expression according to the mask tree list.  */
2868           index = count2;
2869           tmp = mask;
2870           if (tmp != NULL)
2871             maskexpr = gfc_build_array_ref (tmp, index);
2872           else
2873             maskexpr = NULL;
2874
2875           tmp = TREE_CHAIN (tmp);
2876           while (tmp)
2877             {
2878               tmp1 = gfc_build_array_ref (tmp, index);
2879               maskexpr = build2 (TRUTH_AND_EXPR, TREE_TYPE (tmp1),
2880                                  maskexpr, tmp1);
2881               tmp = TREE_CHAIN (tmp);
2882             }
2883           /* Use the scalar assignment as is.  */
2884           tmp = gfc_trans_scalar_assign (&lse, &rse, expr1->ts.type);
2885           tmp = build3_v (COND_EXPR, maskexpr, tmp, build_empty_stmt ());
2886           gfc_add_expr_to_block (&body, tmp);
2887
2888           /* Increment count2.  */
2889           tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2890                               count2, gfc_index_one_node));
2891           gfc_add_modify_expr (&body, count2, tmp);
2892         }
2893       else
2894         {
2895           /* Increment count1.  */
2896           tmp = fold (build2 (PLUS_EXPR, gfc_array_index_type,
2897                               count1, gfc_index_one_node));
2898           gfc_add_modify_expr (&body, count1, tmp);
2899         }
2900
2901       /* Generate the copying loops.  */
2902       gfc_trans_scalarizing_loops (&loop, &body);
2903
2904       /* Wrap the whole thing up.  */
2905       gfc_add_block_to_block (&block, &loop.pre);
2906       gfc_add_block_to_block (&block, &loop.post);
2907       gfc_cleanup_loop (&loop);
2908     }
2909
2910   return gfc_finish_block (&block);
2911 }
2912
2913
2914 /* Translate the WHERE construct or statement.
2915    This fuction can be called iteratively to translate the nested WHERE
2916    construct or statement.
2917    MASK is the control mask, and PMASK is the pending control mask.
2918    TEMP records the temporary address which must be freed later.  */
2919
2920 static void
2921 gfc_trans_where_2 (gfc_code * code, tree mask, tree pmask,
2922                    forall_info * nested_forall_info, stmtblock_t * block,
2923                    temporary_list ** temp)
2924 {
2925   gfc_expr *expr1;
2926   gfc_expr *expr2;
2927   gfc_code *cblock;
2928   gfc_code *cnext;
2929   tree tmp, tmp1, tmp2;
2930   tree count1, count2;
2931   tree mask_copy;
2932   int need_temp;
2933
2934   /* the WHERE statement or the WHERE construct statement.  */
2935   cblock = code->block;
2936   while (cblock)
2937     {
2938       /* Has mask-expr.  */
2939       if (cblock->expr)
2940         {
2941           /* Ensure that the WHERE mask be evaluated only once.  */
2942           tmp2 = gfc_evaluate_where_mask (cblock->expr, nested_forall_info,
2943                                           &tmp, &tmp1, temp, block);
2944
2945           /* Set the control mask and the pending control mask.  */
2946           /* It's a where-stmt.  */
2947           if (mask == NULL)
2948             {
2949               mask = tmp;
2950               pmask = tmp1;
2951             }
2952           /* It's a nested where-stmt.  */
2953           else if (mask && pmask == NULL)
2954             {
2955               tree tmp2;
2956               /* Use the TREE_CHAIN to list the masks.  */
2957               tmp2 = copy_list (mask);
2958               pmask = chainon (mask, tmp1);
2959               mask = chainon (tmp2, tmp);
2960             }
2961           /* It's a masked-elsewhere-stmt.  */
2962           else if (mask && cblock->expr)
2963             {
2964               tree tmp2;
2965               tmp2 = copy_list (pmask);
2966
2967               mask = pmask;
2968               tmp2 = chainon (tmp2, tmp);
2969               pmask = chainon (mask, tmp1);
2970               mask = tmp2;
2971             }
2972         }
2973       /* It's a elsewhere-stmt. No mask-expr is present.  */
2974       else
2975         mask = pmask;
2976
2977       /* Get the assignment statement of a WHERE statement, or the first
2978          statement in where-body-construct of a WHERE construct.  */
2979       cnext = cblock->next;
2980       while (cnext)
2981         {
2982           switch (cnext->op)
2983             {
2984             /* WHERE assignment statement.  */
2985             case EXEC_ASSIGN:
2986               expr1 = cnext->expr;
2987               expr2 = cnext->expr2;
2988               if (nested_forall_info != NULL)
2989                 {
2990                   int nvar;
2991                   gfc_expr **varexpr;
2992
2993                   nvar = nested_forall_info->nvar;
2994                   varexpr = (gfc_expr **)
2995                             gfc_getmem (nvar * sizeof (gfc_expr *));
2996                   need_temp = gfc_check_dependency (expr1, expr2, varexpr,
2997                                                     nvar);
2998                   if (need_temp)
2999                     gfc_trans_assign_need_temp (expr1, expr2, mask,
3000                                                 nested_forall_info, block);
3001                   else
3002                     {
3003                       /* Variables to control maskexpr.  */
3004                       count1 = gfc_create_var (gfc_array_index_type, "count1");
3005                       count2 = gfc_create_var (gfc_array_index_type, "count2");
3006                       gfc_add_modify_expr (block, count1, gfc_index_zero_node);
3007                       gfc_add_modify_expr (block, count2, gfc_index_zero_node);
3008
3009                       tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3010                                                     count2);
3011                       tmp = gfc_trans_nested_forall_loop (nested_forall_info,
3012                                                           tmp, 1, 1);
3013                       gfc_add_expr_to_block (block, tmp);
3014                     }
3015                 }
3016               else
3017                 {
3018                   /* Variables to control maskexpr.  */
3019                   count1 = gfc_create_var (gfc_array_index_type, "count1");
3020                   count2 = gfc_create_var (gfc_array_index_type, "count2");
3021                   gfc_add_modify_expr (block, count1, gfc_index_zero_node);
3022                   gfc_add_modify_expr (block, count2, gfc_index_zero_node);
3023
3024                   tmp = gfc_trans_where_assign (expr1, expr2, mask, count1,
3025                                                 count2);
3026                   gfc_add_expr_to_block (block, tmp);
3027
3028                 }
3029               break;
3030
3031             /* WHERE or WHERE construct is part of a where-body-construct.  */
3032             case EXEC_WHERE:
3033               /* Ensure that MASK is not modified by next gfc_trans_where_2.  */
3034               mask_copy = copy_list (mask);
3035               gfc_trans_where_2 (cnext, mask_copy, NULL, nested_forall_info,
3036                                  block, temp);
3037               break;
3038
3039             default:
3040               gcc_unreachable ();
3041             }
3042
3043          /* The next statement within the same where-body-construct.  */
3044          cnext = cnext->next;
3045        }
3046     /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt.  */
3047     cblock = cblock->block;
3048   }
3049 }
3050
3051
3052 /* As the WHERE or WHERE construct statement can be nested, we call
3053    gfc_trans_where_2 to do the translation, and pass the initial
3054    NULL values for both the control mask and the pending control mask.  */
3055
3056 tree
3057 gfc_trans_where (gfc_code * code)
3058 {
3059   stmtblock_t block;
3060   temporary_list *temp, *p;
3061   tree args;
3062   tree tmp;
3063
3064   gfc_start_block (&block);
3065   temp = NULL;
3066
3067   gfc_trans_where_2 (code, NULL, NULL, NULL, &block, &temp);
3068
3069   /* Add calls to free temporaries which were dynamically allocated.  */
3070   while (temp)
3071     {
3072       args = gfc_chainon_list (NULL_TREE, temp->temporary);
3073       tmp = gfc_build_function_call (gfor_fndecl_internal_free, args);
3074       gfc_add_expr_to_block (&block, tmp);
3075
3076       p = temp;
3077       temp = temp->next;
3078       gfc_free (p);
3079     }
3080   return gfc_finish_block (&block);
3081 }
3082
3083
3084 /* CYCLE a DO loop. The label decl has already been created by
3085    gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
3086    node at the head of the loop. We must mark the label as used.  */
3087
3088 tree
3089 gfc_trans_cycle (gfc_code * code)
3090 {
3091   tree cycle_label;
3092
3093   cycle_label = TREE_PURPOSE (code->ext.whichloop->backend_decl);
3094   TREE_USED (cycle_label) = 1;
3095   return build1_v (GOTO_EXPR, cycle_label);
3096 }
3097
3098
3099 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
3100    TREE_VALUE (backend_decl) of the gfc_code node at the head of the
3101    loop.  */
3102
3103 tree
3104 gfc_trans_exit (gfc_code * code)
3105 {
3106   tree exit_label;
3107
3108   exit_label = TREE_VALUE (code->ext.whichloop->backend_decl);
3109   TREE_USED (exit_label) = 1;
3110   return build1_v (GOTO_EXPR, exit_label);
3111 }
3112
3113
3114 /* Translate the ALLOCATE statement.  */
3115
3116 tree
3117 gfc_trans_allocate (gfc_code * code)
3118 {
3119   gfc_alloc *al;
3120   gfc_expr *expr;
3121   gfc_se se;
3122   tree tmp;
3123   tree parm;
3124   gfc_ref *ref;
3125   tree stat;
3126   tree pstat;
3127   tree error_label;
3128   stmtblock_t block;
3129
3130   if (!code->ext.alloc_list)
3131     return NULL_TREE;
3132
3133   gfc_start_block (&block);
3134
3135   if (code->expr)
3136     {
3137       tree gfc_int4_type_node = gfc_get_int_type (4);
3138
3139       stat = gfc_create_var (gfc_int4_type_node, "stat");
3140       pstat = gfc_build_addr_expr (NULL, stat);
3141
3142       error_label = gfc_build_label_decl (NULL_TREE);
3143       TREE_USED (error_label) = 1;
3144     }
3145   else
3146     {
3147       pstat = integer_zero_node;
3148       stat = error_label = NULL_TREE;
3149     }
3150
3151
3152   for (al = code->ext.alloc_list; al != NULL; al = al->next)
3153     {
3154       expr = al->expr;
3155
3156       gfc_init_se (&se, NULL);
3157       gfc_start_block (&se.pre);
3158
3159       se.want_pointer = 1;
3160       se.descriptor_only = 1;
3161       gfc_conv_expr (&se, expr);
3162
3163       ref = expr->ref;
3164
3165       /* Find the last reference in the chain.  */
3166       while (ref && ref->next != NULL)
3167         {
3168           gcc_assert (ref->type != REF_ARRAY || ref->u.ar.type == AR_ELEMENT);
3169           ref = ref->next;
3170         }
3171
3172       if (ref != NULL && ref->type == REF_ARRAY)
3173         {
3174           /* An array.  */
3175           gfc_array_allocate (&se, ref, pstat);
3176         }
3177       else
3178         {
3179           /* A scalar or derived type.  */
3180           tree val;
3181
3182           val = gfc_create_var (ppvoid_type_node, "ptr");
3183           tmp = gfc_build_addr_expr (ppvoid_type_node, se.expr);
3184           gfc_add_modify_expr (&se.pre, val, tmp);
3185
3186           tmp = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
3187           parm = gfc_chainon_list (NULL_TREE, val);
3188           parm = gfc_chainon_list (parm, tmp);
3189           parm = gfc_chainon_list (parm, pstat);
3190           tmp = gfc_build_function_call (gfor_fndecl_allocate, parm);
3191           gfc_add_expr_to_block (&se.pre, tmp);
3192
3193           if (code->expr)
3194             {
3195               tmp = build1_v (GOTO_EXPR, error_label);
3196               parm =
3197                 build2 (NE_EXPR, boolean_type_node, stat, integer_zero_node);
3198               tmp = build3_v (COND_EXPR, parm, tmp, build_empty_stmt ());
3199               gfc_add_expr_to_block (&se.pre, tmp);
3200             }
3201         }
3202
3203       tmp = gfc_finish_block (&se.pre);
3204       gfc_add_expr_to_block (&block, tmp);
3205     }
3206
3207   /* Assign the value to the status variable.  */
3208   if (code->expr)
3209     {
3210       tmp = build1_v (LABEL_EXPR, error_label);
3211       gfc_add_expr_to_block (&block, tmp);
3212
3213       gfc_init_se (&se, NULL);
3214       gfc_conv_expr_lhs (&se, code->expr);
3215       tmp = convert (TREE_TYPE (se.expr), stat);
3216       gfc_add_modify_expr (&block, se.expr, tmp);
3217     }
3218
3219   return gfc_finish_block (&block);
3220 }
3221
3222
3223 tree
3224 gfc_trans_deallocate (gfc_code * code)
3225 {
3226   gfc_se se;
3227   gfc_alloc *al;
3228   gfc_expr *expr;
3229   tree var;
3230   tree tmp;
3231   tree type;
3232   stmtblock_t block;
3233
3234   gfc_start_block (&block);
3235
3236   for (al = code->ext.alloc_list; al != NULL; al = al->next)
3237     {
3238       expr = al->expr;
3239       gcc_assert (expr->expr_type == EXPR_VARIABLE);
3240
3241       gfc_init_se (&se, NULL);
3242       gfc_start_block (&se.pre);
3243
3244       se.want_pointer = 1;
3245       se.descriptor_only = 1;
3246       gfc_conv_expr (&se, expr);
3247
3248       if (expr->symtree->n.sym->attr.dimension)
3249         {
3250           tmp = gfc_array_deallocate (se.expr);
3251           gfc_add_expr_to_block (&se.pre, tmp);
3252         }
3253       else
3254         {
3255           type = build_pointer_type (TREE_TYPE (se.expr));
3256           var = gfc_create_var (type, "ptr");
3257           tmp = gfc_build_addr_expr (type, se.expr);
3258           gfc_add_modify_expr (&se.pre, var, tmp);
3259
3260           tmp = gfc_chainon_list (NULL_TREE, var);
3261           tmp = gfc_chainon_list (tmp, integer_zero_node);
3262           tmp = gfc_build_function_call (gfor_fndecl_deallocate, tmp);
3263           gfc_add_expr_to_block (&se.pre, tmp);
3264         }
3265       tmp = gfc_finish_block (&se.pre);
3266       gfc_add_expr_to_block (&block, tmp);
3267     }
3268
3269   return gfc_finish_block (&block);
3270 }
3271