OSDN Git Service

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