OSDN Git Service

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