1 /* Statement translation -- generate GCC trees from gfc_code.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
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
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
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
27 #include "coretypes.h"
29 #include "tree-gimple.h"
36 #include "trans-stmt.h"
37 #include "trans-types.h"
38 #include "trans-array.h"
39 #include "trans-const.h"
41 #include "dependency.h"
43 typedef struct iter_info
49 struct iter_info
*next
;
53 typedef struct forall_info
61 struct forall_info
*outer
;
62 struct forall_info
*next_nest
;
66 static void gfc_trans_where_2 (gfc_code
*, tree
, bool,
67 forall_info
*, stmtblock_t
*);
69 /* Translate a F95 label number to a LABEL_EXPR. */
72 gfc_trans_label_here (gfc_code
* code
)
74 return build1_v (LABEL_EXPR
, gfc_get_label_decl (code
->here
));
78 /* Given a variable expression which has been ASSIGNed to, find the decl
79 containing the auxiliary variables. For variables in common blocks this
83 gfc_conv_label_variable (gfc_se
* se
, gfc_expr
* expr
)
85 gcc_assert (expr
->symtree
->n
.sym
->attr
.assign
== 1);
86 gfc_conv_expr (se
, expr
);
87 /* Deals with variable in common block. Get the field declaration. */
88 if (TREE_CODE (se
->expr
) == COMPONENT_REF
)
89 se
->expr
= TREE_OPERAND (se
->expr
, 1);
90 /* Deals with dummy argument. Get the parameter declaration. */
91 else if (TREE_CODE (se
->expr
) == INDIRECT_REF
)
92 se
->expr
= TREE_OPERAND (se
->expr
, 0);
95 /* Translate a label assignment statement. */
98 gfc_trans_label_assign (gfc_code
* code
)
108 /* Start a new block. */
109 gfc_init_se (&se
, NULL
);
110 gfc_start_block (&se
.pre
);
111 gfc_conv_label_variable (&se
, code
->expr
);
113 len
= GFC_DECL_STRING_LEN (se
.expr
);
114 addr
= GFC_DECL_ASSIGN_ADDR (se
.expr
);
116 label_tree
= gfc_get_label_decl (code
->label
);
118 if (code
->label
->defined
== ST_LABEL_TARGET
)
120 label_tree
= gfc_build_addr_expr (pvoid_type_node
, label_tree
);
121 len_tree
= integer_minus_one_node
;
125 label_str
= code
->label
->format
->value
.character
.string
;
126 label_len
= code
->label
->format
->value
.character
.length
;
127 len_tree
= build_int_cst (NULL_TREE
, label_len
);
128 label_tree
= gfc_build_string_const (label_len
+ 1, label_str
);
129 label_tree
= gfc_build_addr_expr (pvoid_type_node
, label_tree
);
132 gfc_add_modify_expr (&se
.pre
, len
, len_tree
);
133 gfc_add_modify_expr (&se
.pre
, addr
, label_tree
);
135 return gfc_finish_block (&se
.pre
);
138 /* Translate a GOTO statement. */
141 gfc_trans_goto (gfc_code
* code
)
143 locus loc
= code
->loc
;
149 if (code
->label
!= NULL
)
150 return build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label
));
153 gfc_init_se (&se
, NULL
);
154 gfc_start_block (&se
.pre
);
155 gfc_conv_label_variable (&se
, code
->expr
);
156 tmp
= GFC_DECL_STRING_LEN (se
.expr
);
157 tmp
= fold_build2 (NE_EXPR
, boolean_type_node
, tmp
,
158 build_int_cst (TREE_TYPE (tmp
), -1));
159 gfc_trans_runtime_check (tmp
, "Assigned label is not a target label",
162 assigned_goto
= GFC_DECL_ASSIGN_ADDR (se
.expr
);
167 target
= build1 (GOTO_EXPR
, void_type_node
, assigned_goto
);
168 gfc_add_expr_to_block (&se
.pre
, target
);
169 return gfc_finish_block (&se
.pre
);
172 /* Check the label list. */
175 target
= gfc_get_label_decl (code
->label
);
176 tmp
= gfc_build_addr_expr (pvoid_type_node
, target
);
177 tmp
= build2 (EQ_EXPR
, boolean_type_node
, tmp
, assigned_goto
);
178 tmp
= build3_v (COND_EXPR
, tmp
,
179 build1 (GOTO_EXPR
, void_type_node
, target
),
180 build_empty_stmt ());
181 gfc_add_expr_to_block (&se
.pre
, tmp
);
184 while (code
!= NULL
);
185 gfc_trans_runtime_check (boolean_true_node
,
186 "Assigned label is not in the list", &se
.pre
, &loc
);
188 return gfc_finish_block (&se
.pre
);
192 /* Translate an ENTRY statement. Just adds a label for this entry point. */
194 gfc_trans_entry (gfc_code
* code
)
196 return build1_v (LABEL_EXPR
, code
->ext
.entry
->label
);
200 /* Check for dependencies between INTENT(IN) and INTENT(OUT) arguments of
201 elemental subroutines. Make temporaries for output arguments if any such
202 dependencies are found. Output arguments are chosen because internal_unpack
203 can be used, as is, to copy the result back to the variable. */
205 gfc_conv_elemental_dependencies (gfc_se
* se
, gfc_se
* loopse
,
206 gfc_symbol
* sym
, gfc_actual_arglist
* arg
)
208 gfc_actual_arglist
*arg0
;
210 gfc_formal_arglist
*formal
;
211 gfc_loopinfo tmp_loop
;
223 if (loopse
->ss
== NULL
)
228 formal
= sym
->formal
;
230 /* Loop over all the arguments testing for dependencies. */
231 for (; arg
!= NULL
; arg
= arg
->next
, formal
= formal
? formal
->next
: NULL
)
237 /* Obtain the info structure for the current argument. */
239 for (ss
= loopse
->ss
; ss
&& ss
!= gfc_ss_terminator
; ss
= ss
->next
)
243 info
= &ss
->data
.info
;
247 /* If there is a dependency, create a temporary and use it
248 instead of the variable. */
249 fsym
= formal
? formal
->sym
: NULL
;
250 if (e
->expr_type
== EXPR_VARIABLE
252 && fsym
->attr
.intent
== INTENT_OUT
253 && gfc_check_fncall_dependency (e
, INTENT_OUT
, sym
, arg0
))
255 /* Make a local loopinfo for the temporary creation, so that
256 none of the other ss->info's have to be renormalized. */
257 gfc_init_loopinfo (&tmp_loop
);
258 for (n
= 0; n
< info
->dimen
; n
++)
260 tmp_loop
.to
[n
] = loopse
->loop
->to
[n
];
261 tmp_loop
.from
[n
] = loopse
->loop
->from
[n
];
262 tmp_loop
.order
[n
] = loopse
->loop
->order
[n
];
265 /* Generate the temporary. Merge the block so that the
266 declarations are put at the right binding level. */
267 size
= gfc_create_var (gfc_array_index_type
, NULL
);
268 data
= gfc_create_var (pvoid_type_node
, NULL
);
269 gfc_start_block (&block
);
270 tmp
= gfc_typenode_for_spec (&e
->ts
);
271 tmp
= gfc_trans_create_temp_array (&se
->pre
, &se
->post
,
272 &tmp_loop
, info
, tmp
,
273 false, true, false, false);
274 gfc_add_modify_expr (&se
->pre
, size
, tmp
);
275 tmp
= fold_convert (pvoid_type_node
, info
->data
);
276 gfc_add_modify_expr (&se
->pre
, data
, tmp
);
277 gfc_merge_block_scope (&block
);
279 /* Obtain the argument descriptor for unpacking. */
280 gfc_init_se (&parmse
, NULL
);
281 parmse
.want_pointer
= 1;
282 gfc_conv_expr_descriptor (&parmse
, e
, gfc_walk_expr (e
));
283 gfc_add_block_to_block (&se
->pre
, &parmse
.pre
);
285 /* Calculate the offset for the temporary. */
286 offset
= gfc_index_zero_node
;
287 for (n
= 0; n
< info
->dimen
; n
++)
289 tmp
= gfc_conv_descriptor_stride (info
->descriptor
,
291 tmp
= fold_build2 (MULT_EXPR
, gfc_array_index_type
,
292 loopse
->loop
->from
[n
], tmp
);
293 offset
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
296 info
->offset
= gfc_create_var (gfc_array_index_type
, NULL
);
297 gfc_add_modify_expr (&se
->pre
, info
->offset
, offset
);
299 /* Copy the result back using unpack. */
300 tmp
= gfc_chainon_list (NULL_TREE
, parmse
.expr
);
301 tmp
= gfc_chainon_list (tmp
, data
);
302 tmp
= build_function_call_expr (gfor_fndecl_in_unpack
, tmp
);
303 gfc_add_expr_to_block (&se
->post
, tmp
);
305 gfc_add_block_to_block (&se
->post
, &parmse
.post
);
311 /* Translate the CALL statement. Builds a call to an F95 subroutine. */
314 gfc_trans_call (gfc_code
* code
, bool dependency_check
)
318 int has_alternate_specifier
;
320 /* A CALL starts a new block because the actual arguments may have to
321 be evaluated first. */
322 gfc_init_se (&se
, NULL
);
323 gfc_start_block (&se
.pre
);
325 gcc_assert (code
->resolved_sym
);
327 ss
= gfc_ss_terminator
;
328 if (code
->resolved_sym
->attr
.elemental
)
329 ss
= gfc_walk_elemental_function_args (ss
, code
->ext
.actual
, GFC_SS_REFERENCE
);
331 /* Is not an elemental subroutine call with array valued arguments. */
332 if (ss
== gfc_ss_terminator
)
335 /* Translate the call. */
336 has_alternate_specifier
337 = gfc_conv_function_call (&se
, code
->resolved_sym
, code
->ext
.actual
,
340 /* A subroutine without side-effect, by definition, does nothing! */
341 TREE_SIDE_EFFECTS (se
.expr
) = 1;
343 /* Chain the pieces together and return the block. */
344 if (has_alternate_specifier
)
346 gfc_code
*select_code
;
348 select_code
= code
->next
;
349 gcc_assert(select_code
->op
== EXEC_SELECT
);
350 sym
= select_code
->expr
->symtree
->n
.sym
;
351 se
.expr
= convert (gfc_typenode_for_spec (&sym
->ts
), se
.expr
);
352 gfc_add_modify_expr (&se
.pre
, sym
->backend_decl
, se
.expr
);
355 gfc_add_expr_to_block (&se
.pre
, se
.expr
);
357 gfc_add_block_to_block (&se
.pre
, &se
.post
);
362 /* An elemental subroutine call with array valued arguments has
369 /* gfc_walk_elemental_function_args renders the ss chain in the
370 reverse order to the actual argument order. */
371 ss
= gfc_reverse_ss (ss
);
373 /* Initialize the loop. */
374 gfc_init_se (&loopse
, NULL
);
375 gfc_init_loopinfo (&loop
);
376 gfc_add_ss_to_loop (&loop
, ss
);
378 gfc_conv_ss_startstride (&loop
);
379 gfc_conv_loop_setup (&loop
);
380 gfc_mark_ss_chain_used (ss
, 1);
382 /* Convert the arguments, checking for dependencies. */
383 gfc_copy_loopinfo_to_se (&loopse
, &loop
);
386 /* For operator assignment, we need to do dependency checking.
387 We also check the intent of the parameters. */
388 if (dependency_check
)
391 sym
= code
->resolved_sym
;
392 gcc_assert (sym
->formal
->sym
->attr
.intent
= INTENT_OUT
);
393 gcc_assert (sym
->formal
->next
->sym
->attr
.intent
= INTENT_IN
);
394 gfc_conv_elemental_dependencies (&se
, &loopse
, sym
,
398 /* Generate the loop body. */
399 gfc_start_scalarized_body (&loop
, &body
);
400 gfc_init_block (&block
);
402 /* Add the subroutine call to the block. */
403 gfc_conv_function_call (&loopse
, code
->resolved_sym
, code
->ext
.actual
,
405 gfc_add_expr_to_block (&loopse
.pre
, loopse
.expr
);
407 gfc_add_block_to_block (&block
, &loopse
.pre
);
408 gfc_add_block_to_block (&block
, &loopse
.post
);
410 /* Finish up the loop block and the loop. */
411 gfc_add_expr_to_block (&body
, gfc_finish_block (&block
));
412 gfc_trans_scalarizing_loops (&loop
, &body
);
413 gfc_add_block_to_block (&se
.pre
, &loop
.pre
);
414 gfc_add_block_to_block (&se
.pre
, &loop
.post
);
415 gfc_add_block_to_block (&se
.pre
, &se
.post
);
416 gfc_cleanup_loop (&loop
);
419 return gfc_finish_block (&se
.pre
);
423 /* Translate the RETURN statement. */
426 gfc_trans_return (gfc_code
* code ATTRIBUTE_UNUSED
)
434 /* If code->expr is not NULL, this return statement must appear
435 in a subroutine and current_fake_result_decl has already
438 result
= gfc_get_fake_result_decl (NULL
, 0);
441 gfc_warning ("An alternate return at %L without a * dummy argument",
443 return build1_v (GOTO_EXPR
, gfc_get_return_label ());
446 /* Start a new block for this statement. */
447 gfc_init_se (&se
, NULL
);
448 gfc_start_block (&se
.pre
);
450 gfc_conv_expr (&se
, code
->expr
);
452 tmp
= build2 (MODIFY_EXPR
, TREE_TYPE (result
), result
, se
.expr
);
453 gfc_add_expr_to_block (&se
.pre
, tmp
);
455 tmp
= build1_v (GOTO_EXPR
, gfc_get_return_label ());
456 gfc_add_expr_to_block (&se
.pre
, tmp
);
457 gfc_add_block_to_block (&se
.pre
, &se
.post
);
458 return gfc_finish_block (&se
.pre
);
461 return build1_v (GOTO_EXPR
, gfc_get_return_label ());
465 /* Translate the PAUSE statement. We have to translate this statement
466 to a runtime library call. */
469 gfc_trans_pause (gfc_code
* code
)
471 tree gfc_int4_type_node
= gfc_get_int_type (4);
477 /* Start a new block for this statement. */
478 gfc_init_se (&se
, NULL
);
479 gfc_start_block (&se
.pre
);
482 if (code
->expr
== NULL
)
484 tmp
= build_int_cst (gfc_int4_type_node
, code
->ext
.stop_code
);
485 args
= gfc_chainon_list (NULL_TREE
, tmp
);
486 fndecl
= gfor_fndecl_pause_numeric
;
490 gfc_conv_expr_reference (&se
, code
->expr
);
491 args
= gfc_chainon_list (NULL_TREE
, se
.expr
);
492 args
= gfc_chainon_list (args
, se
.string_length
);
493 fndecl
= gfor_fndecl_pause_string
;
496 tmp
= build_function_call_expr (fndecl
, args
);
497 gfc_add_expr_to_block (&se
.pre
, tmp
);
499 gfc_add_block_to_block (&se
.pre
, &se
.post
);
501 return gfc_finish_block (&se
.pre
);
505 /* Translate the STOP statement. We have to translate this statement
506 to a runtime library call. */
509 gfc_trans_stop (gfc_code
* code
)
511 tree gfc_int4_type_node
= gfc_get_int_type (4);
517 /* Start a new block for this statement. */
518 gfc_init_se (&se
, NULL
);
519 gfc_start_block (&se
.pre
);
522 if (code
->expr
== NULL
)
524 tmp
= build_int_cst (gfc_int4_type_node
, code
->ext
.stop_code
);
525 args
= gfc_chainon_list (NULL_TREE
, tmp
);
526 fndecl
= gfor_fndecl_stop_numeric
;
530 gfc_conv_expr_reference (&se
, code
->expr
);
531 args
= gfc_chainon_list (NULL_TREE
, se
.expr
);
532 args
= gfc_chainon_list (args
, se
.string_length
);
533 fndecl
= gfor_fndecl_stop_string
;
536 tmp
= build_function_call_expr (fndecl
, args
);
537 gfc_add_expr_to_block (&se
.pre
, tmp
);
539 gfc_add_block_to_block (&se
.pre
, &se
.post
);
541 return gfc_finish_block (&se
.pre
);
545 /* Generate GENERIC for the IF construct. This function also deals with
546 the simple IF statement, because the front end translates the IF
547 statement into an IF construct.
579 where COND_S is the simplified version of the predicate. PRE_COND_S
580 are the pre side-effects produced by the translation of the
582 We need to build the chain recursively otherwise we run into
583 problems with folding incomplete statements. */
586 gfc_trans_if_1 (gfc_code
* code
)
591 /* Check for an unconditional ELSE clause. */
593 return gfc_trans_code (code
->next
);
595 /* Initialize a statement builder for each block. Puts in NULL_TREEs. */
596 gfc_init_se (&if_se
, NULL
);
597 gfc_start_block (&if_se
.pre
);
599 /* Calculate the IF condition expression. */
600 gfc_conv_expr_val (&if_se
, code
->expr
);
602 /* Translate the THEN clause. */
603 stmt
= gfc_trans_code (code
->next
);
605 /* Translate the ELSE clause. */
607 elsestmt
= gfc_trans_if_1 (code
->block
);
609 elsestmt
= build_empty_stmt ();
611 /* Build the condition expression and add it to the condition block. */
612 stmt
= fold_build3 (COND_EXPR
, void_type_node
, if_se
.expr
, stmt
, elsestmt
);
614 gfc_add_expr_to_block (&if_se
.pre
, stmt
);
616 /* Finish off this statement. */
617 return gfc_finish_block (&if_se
.pre
);
621 gfc_trans_if (gfc_code
* code
)
623 /* Ignore the top EXEC_IF, it only announces an IF construct. The
624 actual code we must translate is in code->block. */
626 return gfc_trans_if_1 (code
->block
);
630 /* Translate an arithmetic IF expression.
632 IF (cond) label1, label2, label3 translates to
644 An optimized version can be generated in case of equal labels.
645 E.g., if label1 is equal to label2, we can translate it to
654 gfc_trans_arithmetic_if (gfc_code
* code
)
662 /* Start a new block. */
663 gfc_init_se (&se
, NULL
);
664 gfc_start_block (&se
.pre
);
666 /* Pre-evaluate COND. */
667 gfc_conv_expr_val (&se
, code
->expr
);
668 se
.expr
= gfc_evaluate_now (se
.expr
, &se
.pre
);
670 /* Build something to compare with. */
671 zero
= gfc_build_const (TREE_TYPE (se
.expr
), integer_zero_node
);
673 if (code
->label
->value
!= code
->label2
->value
)
675 /* If (cond < 0) take branch1 else take branch2.
676 First build jumps to the COND .LT. 0 and the COND .EQ. 0 cases. */
677 branch1
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label
));
678 branch2
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label2
));
680 if (code
->label
->value
!= code
->label3
->value
)
681 tmp
= fold_build2 (LT_EXPR
, boolean_type_node
, se
.expr
, zero
);
683 tmp
= fold_build2 (NE_EXPR
, boolean_type_node
, se
.expr
, zero
);
685 branch1
= fold_build3 (COND_EXPR
, void_type_node
, tmp
, branch1
, branch2
);
688 branch1
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label
));
690 if (code
->label
->value
!= code
->label3
->value
691 && code
->label2
->value
!= code
->label3
->value
)
693 /* if (cond <= 0) take branch1 else take branch2. */
694 branch2
= build1_v (GOTO_EXPR
, gfc_get_label_decl (code
->label3
));
695 tmp
= fold_build2 (LE_EXPR
, boolean_type_node
, se
.expr
, zero
);
696 branch1
= fold_build3 (COND_EXPR
, void_type_node
, tmp
, branch1
, branch2
);
699 /* Append the COND_EXPR to the evaluation of COND, and return. */
700 gfc_add_expr_to_block (&se
.pre
, branch1
);
701 return gfc_finish_block (&se
.pre
);
705 /* Translate the simple DO construct. This is where the loop variable has
706 integer type and step +-1. We can't use this in the general case
707 because integer overflow and floating point errors could give incorrect
709 We translate a do loop from:
711 DO dovar = from, to, step
717 [Evaluate loop bounds and step]
719 if ((step > 0) ? (dovar <= to) : (dovar => to))
725 cond = (dovar == to);
727 if (cond) goto end_label;
732 This helps the optimizers by avoiding the extra induction variable
733 used in the general case. */
736 gfc_trans_simple_do (gfc_code
* code
, stmtblock_t
*pblock
, tree dovar
,
737 tree from
, tree to
, tree step
)
746 type
= TREE_TYPE (dovar
);
748 /* Initialize the DO variable: dovar = from. */
749 gfc_add_modify_expr (pblock
, dovar
, from
);
751 /* Cycle and exit statements are implemented with gotos. */
752 cycle_label
= gfc_build_label_decl (NULL_TREE
);
753 exit_label
= gfc_build_label_decl (NULL_TREE
);
755 /* Put the labels where they can be found later. See gfc_trans_do(). */
756 code
->block
->backend_decl
= tree_cons (cycle_label
, exit_label
, NULL
);
759 gfc_start_block (&body
);
761 /* Main loop body. */
762 tmp
= gfc_trans_code (code
->block
->next
);
763 gfc_add_expr_to_block (&body
, tmp
);
765 /* Label for cycle statements (if needed). */
766 if (TREE_USED (cycle_label
))
768 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
769 gfc_add_expr_to_block (&body
, tmp
);
772 /* Evaluate the loop condition. */
773 cond
= fold_build2 (EQ_EXPR
, boolean_type_node
, dovar
, to
);
774 cond
= gfc_evaluate_now (cond
, &body
);
776 /* Increment the loop variable. */
777 tmp
= fold_build2 (PLUS_EXPR
, type
, dovar
, step
);
778 gfc_add_modify_expr (&body
, dovar
, tmp
);
781 tmp
= build1_v (GOTO_EXPR
, exit_label
);
782 TREE_USED (exit_label
) = 1;
783 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
784 cond
, tmp
, build_empty_stmt ());
785 gfc_add_expr_to_block (&body
, tmp
);
787 /* Finish the loop body. */
788 tmp
= gfc_finish_block (&body
);
789 tmp
= build1_v (LOOP_EXPR
, tmp
);
791 /* Only execute the loop if the number of iterations is positive. */
792 if (tree_int_cst_sgn (step
) > 0)
793 cond
= fold_build2 (LE_EXPR
, boolean_type_node
, dovar
, to
);
795 cond
= fold_build2 (GE_EXPR
, boolean_type_node
, dovar
, to
);
796 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
797 cond
, tmp
, build_empty_stmt ());
798 gfc_add_expr_to_block (pblock
, tmp
);
800 /* Add the exit label. */
801 tmp
= build1_v (LABEL_EXPR
, exit_label
);
802 gfc_add_expr_to_block (pblock
, tmp
);
804 return gfc_finish_block (pblock
);
807 /* Translate the DO construct. This obviously is one of the most
808 important ones to get right with any compiler, but especially
811 We special case some loop forms as described in gfc_trans_simple_do.
812 For other cases we implement them with a separate loop count,
813 as described in the standard.
815 We translate a do loop from:
817 DO dovar = from, to, step
823 [evaluate loop bounds and step]
824 count = (to + step - from) / step;
832 if (count <=0) goto exit_label;
836 TODO: Large loop counts
837 The code above assumes the loop count fits into a signed integer kind,
838 i.e. Does not work for loop counts > 2^31 for integer(kind=4) variables
839 We must support the full range. */
842 gfc_trans_do (gfc_code
* code
)
859 gfc_start_block (&block
);
861 /* Evaluate all the expressions in the iterator. */
862 gfc_init_se (&se
, NULL
);
863 gfc_conv_expr_lhs (&se
, code
->ext
.iterator
->var
);
864 gfc_add_block_to_block (&block
, &se
.pre
);
866 type
= TREE_TYPE (dovar
);
868 gfc_init_se (&se
, NULL
);
869 gfc_conv_expr_val (&se
, code
->ext
.iterator
->start
);
870 gfc_add_block_to_block (&block
, &se
.pre
);
871 from
= gfc_evaluate_now (se
.expr
, &block
);
873 gfc_init_se (&se
, NULL
);
874 gfc_conv_expr_val (&se
, code
->ext
.iterator
->end
);
875 gfc_add_block_to_block (&block
, &se
.pre
);
876 to
= gfc_evaluate_now (se
.expr
, &block
);
878 gfc_init_se (&se
, NULL
);
879 gfc_conv_expr_val (&se
, code
->ext
.iterator
->step
);
880 gfc_add_block_to_block (&block
, &se
.pre
);
881 step
= gfc_evaluate_now (se
.expr
, &block
);
883 /* Special case simple loops. */
884 if (TREE_CODE (type
) == INTEGER_TYPE
885 && (integer_onep (step
)
886 || tree_int_cst_equal (step
, integer_minus_one_node
)))
887 return gfc_trans_simple_do (code
, &block
, dovar
, from
, to
, step
);
889 /* Initialize loop count. This code is executed before we enter the
890 loop body. We generate: count = (to + step - from) / step. */
892 tmp
= fold_build2 (MINUS_EXPR
, type
, step
, from
);
893 tmp
= fold_build2 (PLUS_EXPR
, type
, to
, tmp
);
894 if (TREE_CODE (type
) == INTEGER_TYPE
)
896 tmp
= fold_build2 (TRUNC_DIV_EXPR
, type
, tmp
, step
);
897 count
= gfc_create_var (type
, "count");
901 /* TODO: We could use the same width as the real type.
902 This would probably cause more problems that it solves
903 when we implement "long double" types. */
904 tmp
= fold_build2 (RDIV_EXPR
, type
, tmp
, step
);
905 tmp
= fold_build1 (FIX_TRUNC_EXPR
, gfc_array_index_type
, tmp
);
906 count
= gfc_create_var (gfc_array_index_type
, "count");
908 gfc_add_modify_expr (&block
, count
, tmp
);
910 count_one
= build_int_cst (TREE_TYPE (count
), 1);
912 /* Initialize the DO variable: dovar = from. */
913 gfc_add_modify_expr (&block
, dovar
, from
);
916 gfc_start_block (&body
);
918 /* Cycle and exit statements are implemented with gotos. */
919 cycle_label
= gfc_build_label_decl (NULL_TREE
);
920 exit_label
= gfc_build_label_decl (NULL_TREE
);
922 /* Start with the loop condition. Loop until count <= 0. */
923 cond
= fold_build2 (LE_EXPR
, boolean_type_node
, count
,
924 build_int_cst (TREE_TYPE (count
), 0));
925 tmp
= build1_v (GOTO_EXPR
, exit_label
);
926 TREE_USED (exit_label
) = 1;
927 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
928 cond
, tmp
, build_empty_stmt ());
929 gfc_add_expr_to_block (&body
, tmp
);
931 /* Put these labels where they can be found later. We put the
932 labels in a TREE_LIST node (because TREE_CHAIN is already
933 used). cycle_label goes in TREE_PURPOSE (backend_decl), exit
934 label in TREE_VALUE (backend_decl). */
936 code
->block
->backend_decl
= tree_cons (cycle_label
, exit_label
, NULL
);
938 /* Main loop body. */
939 tmp
= gfc_trans_code (code
->block
->next
);
940 gfc_add_expr_to_block (&body
, tmp
);
942 /* Label for cycle statements (if needed). */
943 if (TREE_USED (cycle_label
))
945 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
946 gfc_add_expr_to_block (&body
, tmp
);
949 /* Increment the loop variable. */
950 tmp
= build2 (PLUS_EXPR
, type
, dovar
, step
);
951 gfc_add_modify_expr (&body
, dovar
, tmp
);
953 /* Decrement the loop count. */
954 tmp
= build2 (MINUS_EXPR
, TREE_TYPE (count
), count
, count_one
);
955 gfc_add_modify_expr (&body
, count
, tmp
);
957 /* End of loop body. */
958 tmp
= gfc_finish_block (&body
);
960 /* The for loop itself. */
961 tmp
= build1_v (LOOP_EXPR
, tmp
);
962 gfc_add_expr_to_block (&block
, tmp
);
964 /* Add the exit label. */
965 tmp
= build1_v (LABEL_EXPR
, exit_label
);
966 gfc_add_expr_to_block (&block
, tmp
);
968 return gfc_finish_block (&block
);
972 /* Translate the DO WHILE construct.
985 if (! cond) goto exit_label;
991 Because the evaluation of the exit condition `cond' may have side
992 effects, we can't do much for empty loop bodies. The backend optimizers
993 should be smart enough to eliminate any dead loops. */
996 gfc_trans_do_while (gfc_code
* code
)
1004 /* Everything we build here is part of the loop body. */
1005 gfc_start_block (&block
);
1007 /* Cycle and exit statements are implemented with gotos. */
1008 cycle_label
= gfc_build_label_decl (NULL_TREE
);
1009 exit_label
= gfc_build_label_decl (NULL_TREE
);
1011 /* Put the labels where they can be found later. See gfc_trans_do(). */
1012 code
->block
->backend_decl
= tree_cons (cycle_label
, exit_label
, NULL
);
1014 /* Create a GIMPLE version of the exit condition. */
1015 gfc_init_se (&cond
, NULL
);
1016 gfc_conv_expr_val (&cond
, code
->expr
);
1017 gfc_add_block_to_block (&block
, &cond
.pre
);
1018 cond
.expr
= fold_build1 (TRUTH_NOT_EXPR
, boolean_type_node
, cond
.expr
);
1020 /* Build "IF (! cond) GOTO exit_label". */
1021 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1022 TREE_USED (exit_label
) = 1;
1023 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
1024 cond
.expr
, tmp
, build_empty_stmt ());
1025 gfc_add_expr_to_block (&block
, tmp
);
1027 /* The main body of the loop. */
1028 tmp
= gfc_trans_code (code
->block
->next
);
1029 gfc_add_expr_to_block (&block
, tmp
);
1031 /* Label for cycle statements (if needed). */
1032 if (TREE_USED (cycle_label
))
1034 tmp
= build1_v (LABEL_EXPR
, cycle_label
);
1035 gfc_add_expr_to_block (&block
, tmp
);
1038 /* End of loop body. */
1039 tmp
= gfc_finish_block (&block
);
1041 gfc_init_block (&block
);
1042 /* Build the loop. */
1043 tmp
= build1_v (LOOP_EXPR
, tmp
);
1044 gfc_add_expr_to_block (&block
, tmp
);
1046 /* Add the exit label. */
1047 tmp
= build1_v (LABEL_EXPR
, exit_label
);
1048 gfc_add_expr_to_block (&block
, tmp
);
1050 return gfc_finish_block (&block
);
1054 /* Translate the SELECT CASE construct for INTEGER case expressions,
1055 without killing all potential optimizations. The problem is that
1056 Fortran allows unbounded cases, but the back-end does not, so we
1057 need to intercept those before we enter the equivalent SWITCH_EXPR
1060 For example, we translate this,
1063 CASE (:100,101,105:115)
1073 to the GENERIC equivalent,
1077 case (minimum value for typeof(expr) ... 100:
1083 case 200 ... (maximum value for typeof(expr):
1100 gfc_trans_integer_select (gfc_code
* code
)
1110 gfc_start_block (&block
);
1112 /* Calculate the switch expression. */
1113 gfc_init_se (&se
, NULL
);
1114 gfc_conv_expr_val (&se
, code
->expr
);
1115 gfc_add_block_to_block (&block
, &se
.pre
);
1117 end_label
= gfc_build_label_decl (NULL_TREE
);
1119 gfc_init_block (&body
);
1121 for (c
= code
->block
; c
; c
= c
->block
)
1123 for (cp
= c
->ext
.case_list
; cp
; cp
= cp
->next
)
1128 /* Assume it's the default case. */
1129 low
= high
= NULL_TREE
;
1133 low
= gfc_conv_constant_to_tree (cp
->low
);
1135 /* If there's only a lower bound, set the high bound to the
1136 maximum value of the case expression. */
1138 high
= TYPE_MAX_VALUE (TREE_TYPE (se
.expr
));
1143 /* Three cases are possible here:
1145 1) There is no lower bound, e.g. CASE (:N).
1146 2) There is a lower bound .NE. high bound, that is
1147 a case range, e.g. CASE (N:M) where M>N (we make
1148 sure that M>N during type resolution).
1149 3) There is a lower bound, and it has the same value
1150 as the high bound, e.g. CASE (N:N). This is our
1151 internal representation of CASE(N).
1153 In the first and second case, we need to set a value for
1154 high. In the third case, we don't because the GCC middle
1155 end represents a single case value by just letting high be
1156 a NULL_TREE. We can't do that because we need to be able
1157 to represent unbounded cases. */
1161 && mpz_cmp (cp
->low
->value
.integer
,
1162 cp
->high
->value
.integer
) != 0))
1163 high
= gfc_conv_constant_to_tree (cp
->high
);
1165 /* Unbounded case. */
1167 low
= TYPE_MIN_VALUE (TREE_TYPE (se
.expr
));
1170 /* Build a label. */
1171 label
= gfc_build_label_decl (NULL_TREE
);
1173 /* Add this case label.
1174 Add parameter 'label', make it match GCC backend. */
1175 tmp
= build3 (CASE_LABEL_EXPR
, void_type_node
, low
, high
, label
);
1176 gfc_add_expr_to_block (&body
, tmp
);
1179 /* Add the statements for this case. */
1180 tmp
= gfc_trans_code (c
->next
);
1181 gfc_add_expr_to_block (&body
, tmp
);
1183 /* Break to the end of the construct. */
1184 tmp
= build1_v (GOTO_EXPR
, end_label
);
1185 gfc_add_expr_to_block (&body
, tmp
);
1188 tmp
= gfc_finish_block (&body
);
1189 tmp
= build3_v (SWITCH_EXPR
, se
.expr
, tmp
, NULL_TREE
);
1190 gfc_add_expr_to_block (&block
, tmp
);
1192 tmp
= build1_v (LABEL_EXPR
, end_label
);
1193 gfc_add_expr_to_block (&block
, tmp
);
1195 return gfc_finish_block (&block
);
1199 /* Translate the SELECT CASE construct for LOGICAL case expressions.
1201 There are only two cases possible here, even though the standard
1202 does allow three cases in a LOGICAL SELECT CASE construct: .TRUE.,
1203 .FALSE., and DEFAULT.
1205 We never generate more than two blocks here. Instead, we always
1206 try to eliminate the DEFAULT case. This way, we can translate this
1207 kind of SELECT construct to a simple
1211 expression in GENERIC. */
1214 gfc_trans_logical_select (gfc_code
* code
)
1217 gfc_code
*t
, *f
, *d
;
1222 /* Assume we don't have any cases at all. */
1225 /* Now see which ones we actually do have. We can have at most two
1226 cases in a single case list: one for .TRUE. and one for .FALSE.
1227 The default case is always separate. If the cases for .TRUE. and
1228 .FALSE. are in the same case list, the block for that case list
1229 always executed, and we don't generate code a COND_EXPR. */
1230 for (c
= code
->block
; c
; c
= c
->block
)
1232 for (cp
= c
->ext
.case_list
; cp
; cp
= cp
->next
)
1236 if (cp
->low
->value
.logical
== 0) /* .FALSE. */
1238 else /* if (cp->value.logical != 0), thus .TRUE. */
1246 /* Start a new block. */
1247 gfc_start_block (&block
);
1249 /* Calculate the switch expression. We always need to do this
1250 because it may have side effects. */
1251 gfc_init_se (&se
, NULL
);
1252 gfc_conv_expr_val (&se
, code
->expr
);
1253 gfc_add_block_to_block (&block
, &se
.pre
);
1255 if (t
== f
&& t
!= NULL
)
1257 /* Cases for .TRUE. and .FALSE. are in the same block. Just
1258 translate the code for these cases, append it to the current
1260 gfc_add_expr_to_block (&block
, gfc_trans_code (t
->next
));
1264 tree true_tree
, false_tree
, stmt
;
1266 true_tree
= build_empty_stmt ();
1267 false_tree
= build_empty_stmt ();
1269 /* If we have a case for .TRUE. and for .FALSE., discard the default case.
1270 Otherwise, if .TRUE. or .FALSE. is missing and there is a default case,
1271 make the missing case the default case. */
1272 if (t
!= NULL
&& f
!= NULL
)
1282 /* Translate the code for each of these blocks, and append it to
1283 the current block. */
1285 true_tree
= gfc_trans_code (t
->next
);
1288 false_tree
= gfc_trans_code (f
->next
);
1290 stmt
= fold_build3 (COND_EXPR
, void_type_node
, se
.expr
,
1291 true_tree
, false_tree
);
1292 gfc_add_expr_to_block (&block
, stmt
);
1295 return gfc_finish_block (&block
);
1299 /* Translate the SELECT CASE construct for CHARACTER case expressions.
1300 Instead of generating compares and jumps, it is far simpler to
1301 generate a data structure describing the cases in order and call a
1302 library subroutine that locates the right case.
1303 This is particularly true because this is the only case where we
1304 might have to dispose of a temporary.
1305 The library subroutine returns a pointer to jump to or NULL if no
1306 branches are to be taken. */
1309 gfc_trans_character_select (gfc_code
*code
)
1311 tree init
, node
, end_label
, tmp
, type
, args
, *labels
;
1313 stmtblock_t block
, body
;
1319 static tree select_struct
;
1320 static tree ss_string1
, ss_string1_len
;
1321 static tree ss_string2
, ss_string2_len
;
1322 static tree ss_target
;
1324 if (select_struct
== NULL
)
1326 tree gfc_int4_type_node
= gfc_get_int_type (4);
1328 select_struct
= make_node (RECORD_TYPE
);
1329 TYPE_NAME (select_struct
) = get_identifier ("_jump_struct");
1332 #define ADD_FIELD(NAME, TYPE) \
1333 ss_##NAME = gfc_add_field_to_struct \
1334 (&(TYPE_FIELDS (select_struct)), select_struct, \
1335 get_identifier (stringize(NAME)), TYPE)
1337 ADD_FIELD (string1
, pchar_type_node
);
1338 ADD_FIELD (string1_len
, gfc_int4_type_node
);
1340 ADD_FIELD (string2
, pchar_type_node
);
1341 ADD_FIELD (string2_len
, gfc_int4_type_node
);
1343 ADD_FIELD (target
, pvoid_type_node
);
1346 gfc_finish_type (select_struct
);
1349 cp
= code
->block
->ext
.case_list
;
1350 while (cp
->left
!= NULL
)
1354 for (d
= cp
; d
; d
= d
->right
)
1358 labels
= gfc_getmem (n
* sizeof (tree
));
1362 for(i
= 0; i
< n
; i
++)
1364 labels
[i
] = gfc_build_label_decl (NULL_TREE
);
1365 TREE_USED (labels
[i
]) = 1;
1366 /* TODO: The gimplifier should do this for us, but it has
1367 inadequacies when dealing with static initializers. */
1368 FORCED_LABEL (labels
[i
]) = 1;
1371 end_label
= gfc_build_label_decl (NULL_TREE
);
1373 /* Generate the body */
1374 gfc_start_block (&block
);
1375 gfc_init_block (&body
);
1377 for (c
= code
->block
; c
; c
= c
->block
)
1379 for (d
= c
->ext
.case_list
; d
; d
= d
->next
)
1381 tmp
= build1_v (LABEL_EXPR
, labels
[d
->n
]);
1382 gfc_add_expr_to_block (&body
, tmp
);
1385 tmp
= gfc_trans_code (c
->next
);
1386 gfc_add_expr_to_block (&body
, tmp
);
1388 tmp
= build1_v (GOTO_EXPR
, end_label
);
1389 gfc_add_expr_to_block (&body
, tmp
);
1392 /* Generate the structure describing the branches */
1396 for(d
= cp
; d
; d
= d
->right
, i
++)
1400 gfc_init_se (&se
, NULL
);
1404 node
= tree_cons (ss_string1
, null_pointer_node
, node
);
1405 node
= tree_cons (ss_string1_len
, integer_zero_node
, node
);
1409 gfc_conv_expr_reference (&se
, d
->low
);
1411 node
= tree_cons (ss_string1
, se
.expr
, node
);
1412 node
= tree_cons (ss_string1_len
, se
.string_length
, node
);
1415 if (d
->high
== NULL
)
1417 node
= tree_cons (ss_string2
, null_pointer_node
, node
);
1418 node
= tree_cons (ss_string2_len
, integer_zero_node
, node
);
1422 gfc_init_se (&se
, NULL
);
1423 gfc_conv_expr_reference (&se
, d
->high
);
1425 node
= tree_cons (ss_string2
, se
.expr
, node
);
1426 node
= tree_cons (ss_string2_len
, se
.string_length
, node
);
1429 tmp
= gfc_build_addr_expr (pvoid_type_node
, labels
[i
]);
1430 node
= tree_cons (ss_target
, tmp
, node
);
1432 tmp
= build_constructor_from_list (select_struct
, nreverse (node
));
1433 init
= tree_cons (NULL_TREE
, tmp
, init
);
1436 type
= build_array_type (select_struct
, build_index_type
1437 (build_int_cst (NULL_TREE
, n
- 1)));
1439 init
= build_constructor_from_list (type
, nreverse(init
));
1440 TREE_CONSTANT (init
) = 1;
1441 TREE_INVARIANT (init
) = 1;
1442 TREE_STATIC (init
) = 1;
1443 /* Create a static variable to hold the jump table. */
1444 tmp
= gfc_create_var (type
, "jumptable");
1445 TREE_CONSTANT (tmp
) = 1;
1446 TREE_INVARIANT (tmp
) = 1;
1447 TREE_STATIC (tmp
) = 1;
1448 DECL_INITIAL (tmp
) = init
;
1451 /* Build an argument list for the library call */
1452 init
= gfc_build_addr_expr (pvoid_type_node
, init
);
1453 args
= gfc_chainon_list (NULL_TREE
, init
);
1455 tmp
= build_int_cst (NULL_TREE
, n
);
1456 args
= gfc_chainon_list (args
, tmp
);
1458 tmp
= gfc_build_addr_expr (pvoid_type_node
, end_label
);
1459 args
= gfc_chainon_list (args
, tmp
);
1461 gfc_init_se (&se
, NULL
);
1462 gfc_conv_expr_reference (&se
, code
->expr
);
1464 args
= gfc_chainon_list (args
, se
.expr
);
1465 args
= gfc_chainon_list (args
, se
.string_length
);
1467 gfc_add_block_to_block (&block
, &se
.pre
);
1469 tmp
= build_function_call_expr (gfor_fndecl_select_string
, args
);
1470 case_label
= gfc_create_var (TREE_TYPE (tmp
), "case_label");
1471 gfc_add_modify_expr (&block
, case_label
, tmp
);
1473 gfc_add_block_to_block (&block
, &se
.post
);
1475 tmp
= build1 (GOTO_EXPR
, void_type_node
, case_label
);
1476 gfc_add_expr_to_block (&block
, tmp
);
1478 tmp
= gfc_finish_block (&body
);
1479 gfc_add_expr_to_block (&block
, tmp
);
1480 tmp
= build1_v (LABEL_EXPR
, end_label
);
1481 gfc_add_expr_to_block (&block
, tmp
);
1486 return gfc_finish_block (&block
);
1490 /* Translate the three variants of the SELECT CASE construct.
1492 SELECT CASEs with INTEGER case expressions can be translated to an
1493 equivalent GENERIC switch statement, and for LOGICAL case
1494 expressions we build one or two if-else compares.
1496 SELECT CASEs with CHARACTER case expressions are a whole different
1497 story, because they don't exist in GENERIC. So we sort them and
1498 do a binary search at runtime.
1500 Fortran has no BREAK statement, and it does not allow jumps from
1501 one case block to another. That makes things a lot easier for
1505 gfc_trans_select (gfc_code
* code
)
1507 gcc_assert (code
&& code
->expr
);
1509 /* Empty SELECT constructs are legal. */
1510 if (code
->block
== NULL
)
1511 return build_empty_stmt ();
1513 /* Select the correct translation function. */
1514 switch (code
->expr
->ts
.type
)
1516 case BT_LOGICAL
: return gfc_trans_logical_select (code
);
1517 case BT_INTEGER
: return gfc_trans_integer_select (code
);
1518 case BT_CHARACTER
: return gfc_trans_character_select (code
);
1520 gfc_internal_error ("gfc_trans_select(): Bad type for case expr.");
1526 /* Generate the loops for a FORALL block. The normal loop format:
1527 count = (end - start + step) / step
1540 gfc_trans_forall_loop (forall_info
*forall_tmp
, int nvar
, tree body
, int mask_flag
)
1548 tree var
, start
, end
, step
;
1551 iter
= forall_tmp
->this_loop
;
1552 for (n
= 0; n
< nvar
; n
++)
1555 start
= iter
->start
;
1559 exit_label
= gfc_build_label_decl (NULL_TREE
);
1560 TREE_USED (exit_label
) = 1;
1562 /* The loop counter. */
1563 count
= gfc_create_var (TREE_TYPE (var
), "count");
1565 /* The body of the loop. */
1566 gfc_init_block (&block
);
1568 /* The exit condition. */
1569 cond
= fold_build2 (LE_EXPR
, boolean_type_node
,
1570 count
, build_int_cst (TREE_TYPE (count
), 0));
1571 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1572 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
1573 cond
, tmp
, build_empty_stmt ());
1574 gfc_add_expr_to_block (&block
, tmp
);
1576 /* The main loop body. */
1577 gfc_add_expr_to_block (&block
, body
);
1579 /* Increment the loop variable. */
1580 tmp
= build2 (PLUS_EXPR
, TREE_TYPE (var
), var
, step
);
1581 gfc_add_modify_expr (&block
, var
, tmp
);
1583 /* Advance to the next mask element. Only do this for the
1585 if (n
== 0 && mask_flag
&& forall_tmp
->mask
)
1587 tree maskindex
= forall_tmp
->maskindex
;
1588 tmp
= build2 (PLUS_EXPR
, gfc_array_index_type
,
1589 maskindex
, gfc_index_one_node
);
1590 gfc_add_modify_expr (&block
, maskindex
, tmp
);
1593 /* Decrement the loop counter. */
1594 tmp
= build2 (MINUS_EXPR
, TREE_TYPE (var
), count
, gfc_index_one_node
);
1595 gfc_add_modify_expr (&block
, count
, tmp
);
1597 body
= gfc_finish_block (&block
);
1599 /* Loop var initialization. */
1600 gfc_init_block (&block
);
1601 gfc_add_modify_expr (&block
, var
, start
);
1603 /* Initialize maskindex counter. Only do this before the
1605 if (n
== nvar
- 1 && mask_flag
&& forall_tmp
->mask
)
1606 gfc_add_modify_expr (&block
, forall_tmp
->maskindex
,
1607 gfc_index_zero_node
);
1609 /* Initialize the loop counter. */
1610 tmp
= fold_build2 (MINUS_EXPR
, TREE_TYPE (var
), step
, start
);
1611 tmp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (var
), end
, tmp
);
1612 tmp
= fold_build2 (TRUNC_DIV_EXPR
, TREE_TYPE (var
), tmp
, step
);
1613 gfc_add_modify_expr (&block
, count
, tmp
);
1615 /* The loop expression. */
1616 tmp
= build1_v (LOOP_EXPR
, body
);
1617 gfc_add_expr_to_block (&block
, tmp
);
1619 /* The exit label. */
1620 tmp
= build1_v (LABEL_EXPR
, exit_label
);
1621 gfc_add_expr_to_block (&block
, tmp
);
1623 body
= gfc_finish_block (&block
);
1630 /* Generate the body and loops according to MASK_FLAG and NEST_FLAG.
1631 if MASK_FLAG is nonzero, the body is controlled by maskes in forall
1632 nest, otherwise, the body is not controlled by maskes.
1633 if NEST_FLAG is nonzero, generate loops for nested forall, otherwise,
1634 only generate loops for the current forall level. */
1637 gfc_trans_nested_forall_loop (forall_info
* nested_forall_info
, tree body
,
1638 int mask_flag
, int nest_flag
)
1642 forall_info
*forall_tmp
;
1643 tree pmask
, mask
, maskindex
;
1645 forall_tmp
= nested_forall_info
;
1646 /* Generate loops for nested forall. */
1649 while (forall_tmp
->next_nest
!= NULL
)
1650 forall_tmp
= forall_tmp
->next_nest
;
1651 while (forall_tmp
!= NULL
)
1653 /* Generate body with masks' control. */
1656 pmask
= forall_tmp
->pmask
;
1657 mask
= forall_tmp
->mask
;
1658 maskindex
= forall_tmp
->maskindex
;
1662 /* If a mask was specified make the assignment conditional. */
1664 tmp
= build_fold_indirect_ref (mask
);
1667 tmp
= gfc_build_array_ref (tmp
, maskindex
);
1669 body
= build3_v (COND_EXPR
, tmp
, body
, build_empty_stmt ());
1672 nvar
= forall_tmp
->nvar
;
1673 body
= gfc_trans_forall_loop (forall_tmp
, nvar
, body
, mask_flag
);
1674 forall_tmp
= forall_tmp
->outer
;
1679 nvar
= forall_tmp
->nvar
;
1680 body
= gfc_trans_forall_loop (forall_tmp
, nvar
, body
, mask_flag
);
1687 /* Allocate data for holding a temporary array. Returns either a local
1688 temporary array or a pointer variable. */
1691 gfc_do_allocate (tree bytesize
, tree size
, tree
* pdata
, stmtblock_t
* pblock
,
1699 if (INTEGER_CST_P (size
))
1701 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
, size
,
1702 gfc_index_one_node
);
1707 type
= build_range_type (gfc_array_index_type
, gfc_index_zero_node
, tmp
);
1708 type
= build_array_type (elem_type
, type
);
1709 if (gfc_can_put_var_on_stack (bytesize
))
1711 gcc_assert (INTEGER_CST_P (size
));
1712 tmpvar
= gfc_create_var (type
, "temp");
1717 tmpvar
= gfc_create_var (build_pointer_type (type
), "temp");
1718 *pdata
= convert (pvoid_type_node
, tmpvar
);
1720 args
= gfc_chainon_list (NULL_TREE
, bytesize
);
1721 if (gfc_index_integer_kind
== 4)
1722 tmp
= gfor_fndecl_internal_malloc
;
1723 else if (gfc_index_integer_kind
== 8)
1724 tmp
= gfor_fndecl_internal_malloc64
;
1727 tmp
= build_function_call_expr (tmp
, args
);
1728 tmp
= convert (TREE_TYPE (tmpvar
), tmp
);
1729 gfc_add_modify_expr (pblock
, tmpvar
, tmp
);
1735 /* Generate codes to copy the temporary to the actual lhs. */
1738 generate_loop_for_temp_to_lhs (gfc_expr
*expr
, tree tmp1
, tree count3
,
1739 tree count1
, tree wheremask
, bool invert
)
1743 stmtblock_t block
, body
;
1749 lss
= gfc_walk_expr (expr
);
1751 if (lss
== gfc_ss_terminator
)
1753 gfc_start_block (&block
);
1755 gfc_init_se (&lse
, NULL
);
1757 /* Translate the expression. */
1758 gfc_conv_expr (&lse
, expr
);
1760 /* Form the expression for the temporary. */
1761 tmp
= gfc_build_array_ref (tmp1
, count1
);
1763 /* Use the scalar assignment as is. */
1764 gfc_add_block_to_block (&block
, &lse
.pre
);
1765 gfc_add_modify_expr (&block
, lse
.expr
, tmp
);
1766 gfc_add_block_to_block (&block
, &lse
.post
);
1768 /* Increment the count1. */
1769 tmp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (count1
), count1
,
1770 gfc_index_one_node
);
1771 gfc_add_modify_expr (&block
, count1
, tmp
);
1773 tmp
= gfc_finish_block (&block
);
1777 gfc_start_block (&block
);
1779 gfc_init_loopinfo (&loop1
);
1780 gfc_init_se (&rse
, NULL
);
1781 gfc_init_se (&lse
, NULL
);
1783 /* Associate the lss with the loop. */
1784 gfc_add_ss_to_loop (&loop1
, lss
);
1786 /* Calculate the bounds of the scalarization. */
1787 gfc_conv_ss_startstride (&loop1
);
1788 /* Setup the scalarizing loops. */
1789 gfc_conv_loop_setup (&loop1
);
1791 gfc_mark_ss_chain_used (lss
, 1);
1793 /* Start the scalarized loop body. */
1794 gfc_start_scalarized_body (&loop1
, &body
);
1796 /* Setup the gfc_se structures. */
1797 gfc_copy_loopinfo_to_se (&lse
, &loop1
);
1800 /* Form the expression of the temporary. */
1801 if (lss
!= gfc_ss_terminator
)
1802 rse
.expr
= gfc_build_array_ref (tmp1
, count1
);
1803 /* Translate expr. */
1804 gfc_conv_expr (&lse
, expr
);
1806 /* Use the scalar assignment. */
1807 rse
.string_length
= lse
.string_length
;
1808 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr
->ts
, false, false);
1810 /* Form the mask expression according to the mask tree list. */
1813 wheremaskexpr
= gfc_build_array_ref (wheremask
, count3
);
1815 wheremaskexpr
= fold_build1 (TRUTH_NOT_EXPR
,
1816 TREE_TYPE (wheremaskexpr
),
1818 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
1819 wheremaskexpr
, tmp
, build_empty_stmt ());
1822 gfc_add_expr_to_block (&body
, tmp
);
1824 /* Increment count1. */
1825 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1826 count1
, gfc_index_one_node
);
1827 gfc_add_modify_expr (&body
, count1
, tmp
);
1829 /* Increment count3. */
1832 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1833 count3
, gfc_index_one_node
);
1834 gfc_add_modify_expr (&body
, count3
, tmp
);
1837 /* Generate the copying loops. */
1838 gfc_trans_scalarizing_loops (&loop1
, &body
);
1839 gfc_add_block_to_block (&block
, &loop1
.pre
);
1840 gfc_add_block_to_block (&block
, &loop1
.post
);
1841 gfc_cleanup_loop (&loop1
);
1843 tmp
= gfc_finish_block (&block
);
1849 /* Generate codes to copy rhs to the temporary. TMP1 is the address of
1850 temporary, LSS and RSS are formed in function compute_inner_temp_size(),
1851 and should not be freed. WHEREMASK is the conditional execution mask
1852 whose sense may be inverted by INVERT. */
1855 generate_loop_for_rhs_to_temp (gfc_expr
*expr2
, tree tmp1
, tree count3
,
1856 tree count1
, gfc_ss
*lss
, gfc_ss
*rss
,
1857 tree wheremask
, bool invert
)
1859 stmtblock_t block
, body1
;
1866 gfc_start_block (&block
);
1868 gfc_init_se (&rse
, NULL
);
1869 gfc_init_se (&lse
, NULL
);
1871 if (lss
== gfc_ss_terminator
)
1873 gfc_init_block (&body1
);
1874 gfc_conv_expr (&rse
, expr2
);
1875 lse
.expr
= gfc_build_array_ref (tmp1
, count1
);
1879 /* Initialize the loop. */
1880 gfc_init_loopinfo (&loop
);
1882 /* We may need LSS to determine the shape of the expression. */
1883 gfc_add_ss_to_loop (&loop
, lss
);
1884 gfc_add_ss_to_loop (&loop
, rss
);
1886 gfc_conv_ss_startstride (&loop
);
1887 gfc_conv_loop_setup (&loop
);
1889 gfc_mark_ss_chain_used (rss
, 1);
1890 /* Start the loop body. */
1891 gfc_start_scalarized_body (&loop
, &body1
);
1893 /* Translate the expression. */
1894 gfc_copy_loopinfo_to_se (&rse
, &loop
);
1896 gfc_conv_expr (&rse
, expr2
);
1898 /* Form the expression of the temporary. */
1899 lse
.expr
= gfc_build_array_ref (tmp1
, count1
);
1902 /* Use the scalar assignment. */
1903 lse
.string_length
= rse
.string_length
;
1904 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr2
->ts
, true,
1905 expr2
->expr_type
== EXPR_VARIABLE
);
1907 /* Form the mask expression according to the mask tree list. */
1910 wheremaskexpr
= gfc_build_array_ref (wheremask
, count3
);
1912 wheremaskexpr
= fold_build1 (TRUTH_NOT_EXPR
,
1913 TREE_TYPE (wheremaskexpr
),
1915 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
1916 wheremaskexpr
, tmp
, build_empty_stmt ());
1919 gfc_add_expr_to_block (&body1
, tmp
);
1921 if (lss
== gfc_ss_terminator
)
1923 gfc_add_block_to_block (&block
, &body1
);
1925 /* Increment count1. */
1926 tmp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (count1
), count1
,
1927 gfc_index_one_node
);
1928 gfc_add_modify_expr (&block
, count1
, tmp
);
1932 /* Increment count1. */
1933 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1934 count1
, gfc_index_one_node
);
1935 gfc_add_modify_expr (&body1
, count1
, tmp
);
1937 /* Increment count3. */
1940 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
1941 count3
, gfc_index_one_node
);
1942 gfc_add_modify_expr (&body1
, count3
, tmp
);
1945 /* Generate the copying loops. */
1946 gfc_trans_scalarizing_loops (&loop
, &body1
);
1948 gfc_add_block_to_block (&block
, &loop
.pre
);
1949 gfc_add_block_to_block (&block
, &loop
.post
);
1951 gfc_cleanup_loop (&loop
);
1952 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
1953 as tree nodes in SS may not be valid in different scope. */
1956 tmp
= gfc_finish_block (&block
);
1961 /* Calculate the size of temporary needed in the assignment inside forall.
1962 LSS and RSS are filled in this function. */
1965 compute_inner_temp_size (gfc_expr
*expr1
, gfc_expr
*expr2
,
1966 stmtblock_t
* pblock
,
1967 gfc_ss
**lss
, gfc_ss
**rss
)
1975 *lss
= gfc_walk_expr (expr1
);
1978 size
= gfc_index_one_node
;
1979 if (*lss
!= gfc_ss_terminator
)
1981 gfc_init_loopinfo (&loop
);
1983 /* Walk the RHS of the expression. */
1984 *rss
= gfc_walk_expr (expr2
);
1985 if (*rss
== gfc_ss_terminator
)
1987 /* The rhs is scalar. Add a ss for the expression. */
1988 *rss
= gfc_get_ss ();
1989 (*rss
)->next
= gfc_ss_terminator
;
1990 (*rss
)->type
= GFC_SS_SCALAR
;
1991 (*rss
)->expr
= expr2
;
1994 /* Associate the SS with the loop. */
1995 gfc_add_ss_to_loop (&loop
, *lss
);
1996 /* We don't actually need to add the rhs at this point, but it might
1997 make guessing the loop bounds a bit easier. */
1998 gfc_add_ss_to_loop (&loop
, *rss
);
2000 /* We only want the shape of the expression, not rest of the junk
2001 generated by the scalarizer. */
2002 loop
.array_parameter
= 1;
2004 /* Calculate the bounds of the scalarization. */
2005 save_flag
= flag_bounds_check
;
2006 flag_bounds_check
= 0;
2007 gfc_conv_ss_startstride (&loop
);
2008 flag_bounds_check
= save_flag
;
2009 gfc_conv_loop_setup (&loop
);
2011 /* Figure out how many elements we need. */
2012 for (i
= 0; i
< loop
.dimen
; i
++)
2014 tmp
= fold_build2 (MINUS_EXPR
, gfc_array_index_type
,
2015 gfc_index_one_node
, loop
.from
[i
]);
2016 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2018 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
, tmp
);
2020 gfc_add_block_to_block (pblock
, &loop
.pre
);
2021 size
= gfc_evaluate_now (size
, pblock
);
2022 gfc_add_block_to_block (pblock
, &loop
.post
);
2024 /* TODO: write a function that cleans up a loopinfo without freeing
2025 the SS chains. Currently a NOP. */
2032 /* Calculate the overall iterator number of the nested forall construct. */
2035 compute_overall_iter_number (forall_info
*nested_forall_info
, tree inner_size
,
2036 stmtblock_t
*inner_size_body
, stmtblock_t
*block
)
2041 /* TODO: optimizing the computing process. */
2042 number
= gfc_create_var (gfc_array_index_type
, "num");
2043 gfc_add_modify_expr (block
, number
, gfc_index_zero_node
);
2045 gfc_start_block (&body
);
2046 if (inner_size_body
)
2047 gfc_add_block_to_block (&body
, inner_size_body
);
2048 if (nested_forall_info
)
2049 tmp
= build2 (PLUS_EXPR
, gfc_array_index_type
, number
,
2053 gfc_add_modify_expr (&body
, number
, tmp
);
2054 tmp
= gfc_finish_block (&body
);
2056 /* Generate loops. */
2057 if (nested_forall_info
!= NULL
)
2058 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 0, 1);
2060 gfc_add_expr_to_block (block
, tmp
);
2066 /* Allocate temporary for forall construct. SIZE is the size of temporary
2067 needed. PTEMP1 is returned for space free. */
2070 allocate_temp_for_forall_nest_1 (tree type
, tree size
, stmtblock_t
* block
,
2078 unit
= TYPE_SIZE_UNIT (type
);
2079 bytesize
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
, unit
);
2082 temp1
= gfc_do_allocate (bytesize
, size
, ptemp1
, block
, type
);
2085 tmp
= build_fold_indirect_ref (temp1
);
2093 /* Allocate temporary for forall construct according to the information in
2094 nested_forall_info. INNER_SIZE is the size of temporary needed in the
2095 assignment inside forall. PTEMP1 is returned for space free. */
2098 allocate_temp_for_forall_nest (forall_info
* nested_forall_info
, tree type
,
2099 tree inner_size
, stmtblock_t
* inner_size_body
,
2100 stmtblock_t
* block
, tree
* ptemp1
)
2104 /* Calculate the total size of temporary needed in forall construct. */
2105 size
= compute_overall_iter_number (nested_forall_info
, inner_size
,
2106 inner_size_body
, block
);
2108 return allocate_temp_for_forall_nest_1 (type
, size
, block
, ptemp1
);
2112 /* Handle assignments inside forall which need temporary.
2114 forall (i=start:end:stride; maskexpr)
2117 (where e,f<i> are arbitrary expressions possibly involving i
2118 and there is a dependency between e<i> and f<i>)
2120 masktmp(:) = maskexpr(:)
2125 for (i = start; i <= end; i += stride)
2129 for (i = start; i <= end; i += stride)
2131 if (masktmp[maskindex++])
2132 tmp[count1++] = f<i>
2136 for (i = start; i <= end; i += stride)
2138 if (masktmp[maskindex++])
2139 e<i> = tmp[count1++]
2144 gfc_trans_assign_need_temp (gfc_expr
* expr1
, gfc_expr
* expr2
,
2145 tree wheremask
, bool invert
,
2146 forall_info
* nested_forall_info
,
2147 stmtblock_t
* block
)
2155 stmtblock_t inner_size_body
;
2157 /* Create vars. count1 is the current iterator number of the nested
2159 count1
= gfc_create_var (gfc_array_index_type
, "count1");
2161 /* Count is the wheremask index. */
2164 count
= gfc_create_var (gfc_array_index_type
, "count");
2165 gfc_add_modify_expr (block
, count
, gfc_index_zero_node
);
2170 /* Initialize count1. */
2171 gfc_add_modify_expr (block
, count1
, gfc_index_zero_node
);
2173 /* Calculate the size of temporary needed in the assignment. Return loop, lss
2174 and rss which are used in function generate_loop_for_rhs_to_temp(). */
2175 gfc_init_block (&inner_size_body
);
2176 inner_size
= compute_inner_temp_size (expr1
, expr2
, &inner_size_body
,
2179 /* The type of LHS. Used in function allocate_temp_for_forall_nest */
2180 type
= gfc_typenode_for_spec (&expr1
->ts
);
2182 /* Allocate temporary for nested forall construct according to the
2183 information in nested_forall_info and inner_size. */
2184 tmp1
= allocate_temp_for_forall_nest (nested_forall_info
, type
, inner_size
,
2185 &inner_size_body
, block
, &ptemp1
);
2187 /* Generate codes to copy rhs to the temporary . */
2188 tmp
= generate_loop_for_rhs_to_temp (expr2
, tmp1
, count
, count1
, lss
, rss
,
2191 /* Generate body and loops according to the information in
2192 nested_forall_info. */
2193 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1, 1);
2194 gfc_add_expr_to_block (block
, tmp
);
2197 gfc_add_modify_expr (block
, count1
, gfc_index_zero_node
);
2201 gfc_add_modify_expr (block
, count
, gfc_index_zero_node
);
2203 /* Generate codes to copy the temporary to lhs. */
2204 tmp
= generate_loop_for_temp_to_lhs (expr1
, tmp1
, count
, count1
,
2207 /* Generate body and loops according to the information in
2208 nested_forall_info. */
2209 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1, 1);
2210 gfc_add_expr_to_block (block
, tmp
);
2214 /* Free the temporary. */
2215 tmp
= gfc_chainon_list (NULL_TREE
, ptemp1
);
2216 tmp
= build_function_call_expr (gfor_fndecl_internal_free
, tmp
);
2217 gfc_add_expr_to_block (block
, tmp
);
2222 /* Translate pointer assignment inside FORALL which need temporary. */
2225 gfc_trans_pointer_assign_need_temp (gfc_expr
* expr1
, gfc_expr
* expr2
,
2226 forall_info
* nested_forall_info
,
2227 stmtblock_t
* block
)
2241 tree tmp
, tmp1
, ptemp1
;
2243 count
= gfc_create_var (gfc_array_index_type
, "count");
2244 gfc_add_modify_expr (block
, count
, gfc_index_zero_node
);
2246 inner_size
= integer_one_node
;
2247 lss
= gfc_walk_expr (expr1
);
2248 rss
= gfc_walk_expr (expr2
);
2249 if (lss
== gfc_ss_terminator
)
2251 type
= gfc_typenode_for_spec (&expr1
->ts
);
2252 type
= build_pointer_type (type
);
2254 /* Allocate temporary for nested forall construct according to the
2255 information in nested_forall_info and inner_size. */
2256 tmp1
= allocate_temp_for_forall_nest (nested_forall_info
, type
,
2257 inner_size
, NULL
, block
, &ptemp1
);
2258 gfc_start_block (&body
);
2259 gfc_init_se (&lse
, NULL
);
2260 lse
.expr
= gfc_build_array_ref (tmp1
, count
);
2261 gfc_init_se (&rse
, NULL
);
2262 rse
.want_pointer
= 1;
2263 gfc_conv_expr (&rse
, expr2
);
2264 gfc_add_block_to_block (&body
, &rse
.pre
);
2265 gfc_add_modify_expr (&body
, lse
.expr
,
2266 fold_convert (TREE_TYPE (lse
.expr
), rse
.expr
));
2267 gfc_add_block_to_block (&body
, &rse
.post
);
2269 /* Increment count. */
2270 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2271 count
, gfc_index_one_node
);
2272 gfc_add_modify_expr (&body
, count
, tmp
);
2274 tmp
= gfc_finish_block (&body
);
2276 /* Generate body and loops according to the information in
2277 nested_forall_info. */
2278 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1, 1);
2279 gfc_add_expr_to_block (block
, tmp
);
2282 gfc_add_modify_expr (block
, count
, gfc_index_zero_node
);
2284 gfc_start_block (&body
);
2285 gfc_init_se (&lse
, NULL
);
2286 gfc_init_se (&rse
, NULL
);
2287 rse
.expr
= gfc_build_array_ref (tmp1
, count
);
2288 lse
.want_pointer
= 1;
2289 gfc_conv_expr (&lse
, expr1
);
2290 gfc_add_block_to_block (&body
, &lse
.pre
);
2291 gfc_add_modify_expr (&body
, lse
.expr
, rse
.expr
);
2292 gfc_add_block_to_block (&body
, &lse
.post
);
2293 /* Increment count. */
2294 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2295 count
, gfc_index_one_node
);
2296 gfc_add_modify_expr (&body
, count
, tmp
);
2297 tmp
= gfc_finish_block (&body
);
2299 /* Generate body and loops according to the information in
2300 nested_forall_info. */
2301 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1, 1);
2302 gfc_add_expr_to_block (block
, tmp
);
2306 gfc_init_loopinfo (&loop
);
2308 /* Associate the SS with the loop. */
2309 gfc_add_ss_to_loop (&loop
, rss
);
2311 /* Setup the scalarizing loops and bounds. */
2312 gfc_conv_ss_startstride (&loop
);
2314 gfc_conv_loop_setup (&loop
);
2316 info
= &rss
->data
.info
;
2317 desc
= info
->descriptor
;
2319 /* Make a new descriptor. */
2320 parmtype
= gfc_get_element_type (TREE_TYPE (desc
));
2321 parmtype
= gfc_get_array_type_bounds (parmtype
, loop
.dimen
,
2322 loop
.from
, loop
.to
, 1);
2324 /* Allocate temporary for nested forall construct. */
2325 tmp1
= allocate_temp_for_forall_nest (nested_forall_info
, parmtype
,
2326 inner_size
, NULL
, block
, &ptemp1
);
2327 gfc_start_block (&body
);
2328 gfc_init_se (&lse
, NULL
);
2329 lse
.expr
= gfc_build_array_ref (tmp1
, count
);
2330 lse
.direct_byref
= 1;
2331 rss
= gfc_walk_expr (expr2
);
2332 gfc_conv_expr_descriptor (&lse
, expr2
, rss
);
2334 gfc_add_block_to_block (&body
, &lse
.pre
);
2335 gfc_add_block_to_block (&body
, &lse
.post
);
2337 /* Increment count. */
2338 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2339 count
, gfc_index_one_node
);
2340 gfc_add_modify_expr (&body
, count
, tmp
);
2342 tmp
= gfc_finish_block (&body
);
2344 /* Generate body and loops according to the information in
2345 nested_forall_info. */
2346 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1, 1);
2347 gfc_add_expr_to_block (block
, tmp
);
2350 gfc_add_modify_expr (block
, count
, gfc_index_zero_node
);
2352 parm
= gfc_build_array_ref (tmp1
, count
);
2353 lss
= gfc_walk_expr (expr1
);
2354 gfc_init_se (&lse
, NULL
);
2355 gfc_conv_expr_descriptor (&lse
, expr1
, lss
);
2356 gfc_add_modify_expr (&lse
.pre
, lse
.expr
, parm
);
2357 gfc_start_block (&body
);
2358 gfc_add_block_to_block (&body
, &lse
.pre
);
2359 gfc_add_block_to_block (&body
, &lse
.post
);
2361 /* Increment count. */
2362 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2363 count
, gfc_index_one_node
);
2364 gfc_add_modify_expr (&body
, count
, tmp
);
2366 tmp
= gfc_finish_block (&body
);
2368 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp
, 1, 1);
2369 gfc_add_expr_to_block (block
, tmp
);
2371 /* Free the temporary. */
2374 tmp
= gfc_chainon_list (NULL_TREE
, ptemp1
);
2375 tmp
= build_function_call_expr (gfor_fndecl_internal_free
, tmp
);
2376 gfc_add_expr_to_block (block
, tmp
);
2381 /* FORALL and WHERE statements are really nasty, especially when you nest
2382 them. All the rhs of a forall assignment must be evaluated before the
2383 actual assignments are performed. Presumably this also applies to all the
2384 assignments in an inner where statement. */
2386 /* Generate code for a FORALL statement. Any temporaries are allocated as a
2387 linear array, relying on the fact that we process in the same order in all
2390 forall (i=start:end:stride; maskexpr)
2394 (where e,f,g,h<i> are arbitrary expressions possibly involving i)
2396 count = ((end + 1 - start) / stride)
2397 masktmp(:) = maskexpr(:)
2400 for (i = start; i <= end; i += stride)
2402 if (masktmp[maskindex++])
2406 for (i = start; i <= end; i += stride)
2408 if (masktmp[maskindex++])
2412 Note that this code only works when there are no dependencies.
2413 Forall loop with array assignments and data dependencies are a real pain,
2414 because the size of the temporary cannot always be determined before the
2415 loop is executed. This problem is compounded by the presence of nested
2420 gfc_trans_forall_1 (gfc_code
* code
, forall_info
* nested_forall_info
)
2442 gfc_forall_iterator
*fa
;
2445 gfc_saved_var
*saved_vars
;
2446 iter_info
*this_forall
, *iter_tmp
;
2447 forall_info
*info
, *forall_tmp
;
2449 gfc_start_block (&block
);
2452 /* Count the FORALL index number. */
2453 for (fa
= code
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
2457 /* Allocate the space for var, start, end, step, varexpr. */
2458 var
= (tree
*) gfc_getmem (nvar
* sizeof (tree
));
2459 start
= (tree
*) gfc_getmem (nvar
* sizeof (tree
));
2460 end
= (tree
*) gfc_getmem (nvar
* sizeof (tree
));
2461 step
= (tree
*) gfc_getmem (nvar
* sizeof (tree
));
2462 varexpr
= (gfc_expr
**) gfc_getmem (nvar
* sizeof (gfc_expr
*));
2463 saved_vars
= (gfc_saved_var
*) gfc_getmem (nvar
* sizeof (gfc_saved_var
));
2465 /* Allocate the space for info. */
2466 info
= (forall_info
*) gfc_getmem (sizeof (forall_info
));
2468 for (fa
= code
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
2470 gfc_symbol
*sym
= fa
->var
->symtree
->n
.sym
;
2472 /* allocate space for this_forall. */
2473 this_forall
= (iter_info
*) gfc_getmem (sizeof (iter_info
));
2475 /* Create a temporary variable for the FORALL index. */
2476 tmp
= gfc_typenode_for_spec (&sym
->ts
);
2477 var
[n
] = gfc_create_var (tmp
, sym
->name
);
2478 gfc_shadow_sym (sym
, var
[n
], &saved_vars
[n
]);
2480 /* Record it in this_forall. */
2481 this_forall
->var
= var
[n
];
2483 /* Replace the index symbol's backend_decl with the temporary decl. */
2484 sym
->backend_decl
= var
[n
];
2486 /* Work out the start, end and stride for the loop. */
2487 gfc_init_se (&se
, NULL
);
2488 gfc_conv_expr_val (&se
, fa
->start
);
2489 /* Record it in this_forall. */
2490 this_forall
->start
= se
.expr
;
2491 gfc_add_block_to_block (&block
, &se
.pre
);
2494 gfc_init_se (&se
, NULL
);
2495 gfc_conv_expr_val (&se
, fa
->end
);
2496 /* Record it in this_forall. */
2497 this_forall
->end
= se
.expr
;
2498 gfc_make_safe_expr (&se
);
2499 gfc_add_block_to_block (&block
, &se
.pre
);
2502 gfc_init_se (&se
, NULL
);
2503 gfc_conv_expr_val (&se
, fa
->stride
);
2504 /* Record it in this_forall. */
2505 this_forall
->step
= se
.expr
;
2506 gfc_make_safe_expr (&se
);
2507 gfc_add_block_to_block (&block
, &se
.pre
);
2510 /* Set the NEXT field of this_forall to NULL. */
2511 this_forall
->next
= NULL
;
2512 /* Link this_forall to the info construct. */
2513 if (info
->this_loop
== NULL
)
2514 info
->this_loop
= this_forall
;
2517 iter_tmp
= info
->this_loop
;
2518 while (iter_tmp
->next
!= NULL
)
2519 iter_tmp
= iter_tmp
->next
;
2520 iter_tmp
->next
= this_forall
;
2527 /* Work out the number of elements in the mask array. */
2530 size
= gfc_index_one_node
;
2531 sizevar
= NULL_TREE
;
2533 for (n
= 0; n
< nvar
; n
++)
2535 if (lenvar
&& TREE_TYPE (lenvar
) != TREE_TYPE (start
[n
]))
2538 /* size = (end + step - start) / step. */
2539 tmp
= fold_build2 (MINUS_EXPR
, TREE_TYPE (start
[n
]),
2541 tmp
= fold_build2 (PLUS_EXPR
, TREE_TYPE (end
[n
]), end
[n
], tmp
);
2543 tmp
= fold_build2 (FLOOR_DIV_EXPR
, TREE_TYPE (tmp
), tmp
, step
[n
]);
2544 tmp
= convert (gfc_array_index_type
, tmp
);
2546 size
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
, tmp
);
2549 /* Record the nvar and size of current forall level. */
2553 /* Link the current forall level to nested_forall_info. */
2554 forall_tmp
= nested_forall_info
;
2555 if (forall_tmp
== NULL
)
2556 nested_forall_info
= info
;
2559 while (forall_tmp
->next_nest
!= NULL
)
2560 forall_tmp
= forall_tmp
->next_nest
;
2561 info
->outer
= forall_tmp
;
2562 forall_tmp
->next_nest
= info
;
2565 /* Copy the mask into a temporary variable if required.
2566 For now we assume a mask temporary is needed. */
2569 /* As the mask array can be very big, prefer compact
2571 tree smallest_boolean_type_node
2572 = gfc_get_logical_type (gfc_logical_kinds
[0].kind
);
2574 /* Allocate the mask temporary. */
2575 bytesize
= fold_build2 (MULT_EXPR
, gfc_array_index_type
, size
,
2576 TYPE_SIZE_UNIT (smallest_boolean_type_node
));
2578 mask
= gfc_do_allocate (bytesize
, size
, &pmask
, &block
,
2579 smallest_boolean_type_node
);
2581 maskindex
= gfc_create_var_np (gfc_array_index_type
, "mi");
2582 /* Record them in the info structure. */
2583 info
->pmask
= pmask
;
2585 info
->maskindex
= maskindex
;
2587 gfc_add_modify_expr (&block
, maskindex
, gfc_index_zero_node
);
2589 /* Start of mask assignment loop body. */
2590 gfc_start_block (&body
);
2592 /* Evaluate the mask expression. */
2593 gfc_init_se (&se
, NULL
);
2594 gfc_conv_expr_val (&se
, code
->expr
);
2595 gfc_add_block_to_block (&body
, &se
.pre
);
2597 /* Store the mask. */
2598 se
.expr
= convert (smallest_boolean_type_node
, se
.expr
);
2601 tmp
= build_fold_indirect_ref (mask
);
2604 tmp
= gfc_build_array_ref (tmp
, maskindex
);
2605 gfc_add_modify_expr (&body
, tmp
, se
.expr
);
2607 /* Advance to the next mask element. */
2608 tmp
= build2 (PLUS_EXPR
, gfc_array_index_type
,
2609 maskindex
, gfc_index_one_node
);
2610 gfc_add_modify_expr (&body
, maskindex
, tmp
);
2612 /* Generate the loops. */
2613 tmp
= gfc_finish_block (&body
);
2614 tmp
= gfc_trans_nested_forall_loop (info
, tmp
, 0, 0);
2615 gfc_add_expr_to_block (&block
, tmp
);
2619 /* No mask was specified. */
2620 maskindex
= NULL_TREE
;
2621 mask
= pmask
= NULL_TREE
;
2624 c
= code
->block
->next
;
2626 /* TODO: loop merging in FORALL statements. */
2627 /* Now that we've got a copy of the mask, generate the assignment loops. */
2633 /* A scalar or array assignment. */
2634 need_temp
= gfc_check_dependency (c
->expr
, c
->expr2
, 0);
2635 /* Temporaries due to array assignment data dependencies introduce
2636 no end of problems. */
2638 gfc_trans_assign_need_temp (c
->expr
, c
->expr2
, NULL
, false,
2639 nested_forall_info
, &block
);
2642 /* Use the normal assignment copying routines. */
2643 assign
= gfc_trans_assignment (c
->expr
, c
->expr2
, false);
2645 /* Generate body and loops. */
2646 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, assign
, 1, 1);
2647 gfc_add_expr_to_block (&block
, tmp
);
2653 /* Translate WHERE or WHERE construct nested in FORALL. */
2654 gfc_trans_where_2 (c
, NULL
, false, nested_forall_info
, &block
);
2657 /* Pointer assignment inside FORALL. */
2658 case EXEC_POINTER_ASSIGN
:
2659 need_temp
= gfc_check_dependency (c
->expr
, c
->expr2
, 0);
2661 gfc_trans_pointer_assign_need_temp (c
->expr
, c
->expr2
,
2662 nested_forall_info
, &block
);
2665 /* Use the normal assignment copying routines. */
2666 assign
= gfc_trans_pointer_assignment (c
->expr
, c
->expr2
);
2668 /* Generate body and loops. */
2669 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, assign
,
2671 gfc_add_expr_to_block (&block
, tmp
);
2676 tmp
= gfc_trans_forall_1 (c
, nested_forall_info
);
2677 gfc_add_expr_to_block (&block
, tmp
);
2680 /* Explicit subroutine calls are prevented by the frontend but interface
2681 assignments can legitimately produce them. */
2682 case EXEC_ASSIGN_CALL
:
2683 assign
= gfc_trans_call (c
, true);
2684 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
, assign
, 1, 1);
2685 gfc_add_expr_to_block (&block
, tmp
);
2695 /* Restore the original index variables. */
2696 for (fa
= code
->ext
.forall_iterator
, n
= 0; fa
; fa
= fa
->next
, n
++)
2697 gfc_restore_sym (fa
->var
->symtree
->n
.sym
, &saved_vars
[n
]);
2699 /* Free the space for var, start, end, step, varexpr. */
2705 gfc_free (saved_vars
);
2709 /* Free the temporary for the mask. */
2710 tmp
= gfc_chainon_list (NULL_TREE
, pmask
);
2711 tmp
= build_function_call_expr (gfor_fndecl_internal_free
, tmp
);
2712 gfc_add_expr_to_block (&block
, tmp
);
2715 pushdecl (maskindex
);
2717 return gfc_finish_block (&block
);
2721 /* Translate the FORALL statement or construct. */
2723 tree
gfc_trans_forall (gfc_code
* code
)
2725 return gfc_trans_forall_1 (code
, NULL
);
2729 /* Evaluate the WHERE mask expression, copy its value to a temporary.
2730 If the WHERE construct is nested in FORALL, compute the overall temporary
2731 needed by the WHERE mask expression multiplied by the iterator number of
2733 ME is the WHERE mask expression.
2734 MASK is the current execution mask upon input, whose sense may or may
2735 not be inverted as specified by the INVERT argument.
2736 CMASK is the updated execution mask on output, or NULL if not required.
2737 PMASK is the pending execution mask on output, or NULL if not required.
2738 BLOCK is the block in which to place the condition evaluation loops. */
2741 gfc_evaluate_where_mask (gfc_expr
* me
, forall_info
* nested_forall_info
,
2742 tree mask
, bool invert
, tree cmask
, tree pmask
,
2743 tree mask_type
, stmtblock_t
* block
)
2748 stmtblock_t body
, body1
;
2749 tree count
, cond
, mtmp
;
2752 gfc_init_loopinfo (&loop
);
2754 lss
= gfc_walk_expr (me
);
2755 rss
= gfc_walk_expr (me
);
2757 /* Variable to index the temporary. */
2758 count
= gfc_create_var (gfc_array_index_type
, "count");
2759 /* Initialize count. */
2760 gfc_add_modify_expr (block
, count
, gfc_index_zero_node
);
2762 gfc_start_block (&body
);
2764 gfc_init_se (&rse
, NULL
);
2765 gfc_init_se (&lse
, NULL
);
2767 if (lss
== gfc_ss_terminator
)
2769 gfc_init_block (&body1
);
2773 /* Initialize the loop. */
2774 gfc_init_loopinfo (&loop
);
2776 /* We may need LSS to determine the shape of the expression. */
2777 gfc_add_ss_to_loop (&loop
, lss
);
2778 gfc_add_ss_to_loop (&loop
, rss
);
2780 gfc_conv_ss_startstride (&loop
);
2781 gfc_conv_loop_setup (&loop
);
2783 gfc_mark_ss_chain_used (rss
, 1);
2784 /* Start the loop body. */
2785 gfc_start_scalarized_body (&loop
, &body1
);
2787 /* Translate the expression. */
2788 gfc_copy_loopinfo_to_se (&rse
, &loop
);
2790 gfc_conv_expr (&rse
, me
);
2793 /* Variable to evaluate mask condition. */
2794 cond
= gfc_create_var (mask_type
, "cond");
2795 if (mask
&& (cmask
|| pmask
))
2796 mtmp
= gfc_create_var (mask_type
, "mask");
2797 else mtmp
= NULL_TREE
;
2799 gfc_add_block_to_block (&body1
, &lse
.pre
);
2800 gfc_add_block_to_block (&body1
, &rse
.pre
);
2802 gfc_add_modify_expr (&body1
, cond
, fold_convert (mask_type
, rse
.expr
));
2804 if (mask
&& (cmask
|| pmask
))
2806 tmp
= gfc_build_array_ref (mask
, count
);
2808 tmp
= fold_build1 (TRUTH_NOT_EXPR
, mask_type
, tmp
);
2809 gfc_add_modify_expr (&body1
, mtmp
, tmp
);
2814 tmp1
= gfc_build_array_ref (cmask
, count
);
2817 tmp
= build2 (TRUTH_AND_EXPR
, mask_type
, mtmp
, tmp
);
2818 gfc_add_modify_expr (&body1
, tmp1
, tmp
);
2823 tmp1
= gfc_build_array_ref (pmask
, count
);
2824 tmp
= build1 (TRUTH_NOT_EXPR
, mask_type
, cond
);
2826 tmp
= build2 (TRUTH_AND_EXPR
, mask_type
, mtmp
, tmp
);
2827 gfc_add_modify_expr (&body1
, tmp1
, tmp
);
2830 gfc_add_block_to_block (&body1
, &lse
.post
);
2831 gfc_add_block_to_block (&body1
, &rse
.post
);
2833 if (lss
== gfc_ss_terminator
)
2835 gfc_add_block_to_block (&body
, &body1
);
2839 /* Increment count. */
2840 tmp1
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
, count
,
2841 gfc_index_one_node
);
2842 gfc_add_modify_expr (&body1
, count
, tmp1
);
2844 /* Generate the copying loops. */
2845 gfc_trans_scalarizing_loops (&loop
, &body1
);
2847 gfc_add_block_to_block (&body
, &loop
.pre
);
2848 gfc_add_block_to_block (&body
, &loop
.post
);
2850 gfc_cleanup_loop (&loop
);
2851 /* TODO: Reuse lss and rss when copying temp->lhs. Need to be careful
2852 as tree nodes in SS may not be valid in different scope. */
2855 tmp1
= gfc_finish_block (&body
);
2856 /* If the WHERE construct is inside FORALL, fill the full temporary. */
2857 if (nested_forall_info
!= NULL
)
2858 tmp1
= gfc_trans_nested_forall_loop (nested_forall_info
, tmp1
, 1, 1);
2860 gfc_add_expr_to_block (block
, tmp1
);
2864 /* Translate an assignment statement in a WHERE statement or construct
2865 statement. The MASK expression is used to control which elements
2866 of EXPR1 shall be assigned. The sense of MASK is specified by
2870 gfc_trans_where_assign (gfc_expr
*expr1
, gfc_expr
*expr2
,
2871 tree mask
, bool invert
,
2872 tree count1
, tree count2
)
2877 gfc_ss
*lss_section
;
2884 tree index
, maskexpr
;
2887 /* TODO: handle this special case.
2888 Special case a single function returning an array. */
2889 if (expr2
->expr_type
== EXPR_FUNCTION
&& expr2
->rank
> 0)
2891 tmp
= gfc_trans_arrayfunc_assign (expr1
, expr2
);
2897 /* Assignment of the form lhs = rhs. */
2898 gfc_start_block (&block
);
2900 gfc_init_se (&lse
, NULL
);
2901 gfc_init_se (&rse
, NULL
);
2904 lss
= gfc_walk_expr (expr1
);
2907 /* In each where-assign-stmt, the mask-expr and the variable being
2908 defined shall be arrays of the same shape. */
2909 gcc_assert (lss
!= gfc_ss_terminator
);
2911 /* The assignment needs scalarization. */
2914 /* Find a non-scalar SS from the lhs. */
2915 while (lss_section
!= gfc_ss_terminator
2916 && lss_section
->type
!= GFC_SS_SECTION
)
2917 lss_section
= lss_section
->next
;
2919 gcc_assert (lss_section
!= gfc_ss_terminator
);
2921 /* Initialize the scalarizer. */
2922 gfc_init_loopinfo (&loop
);
2925 rss
= gfc_walk_expr (expr2
);
2926 if (rss
== gfc_ss_terminator
)
2928 /* The rhs is scalar. Add a ss for the expression. */
2929 rss
= gfc_get_ss ();
2930 rss
->next
= gfc_ss_terminator
;
2931 rss
->type
= GFC_SS_SCALAR
;
2935 /* Associate the SS with the loop. */
2936 gfc_add_ss_to_loop (&loop
, lss
);
2937 gfc_add_ss_to_loop (&loop
, rss
);
2939 /* Calculate the bounds of the scalarization. */
2940 gfc_conv_ss_startstride (&loop
);
2942 /* Resolve any data dependencies in the statement. */
2943 gfc_conv_resolve_dependencies (&loop
, lss_section
, rss
);
2945 /* Setup the scalarizing loops. */
2946 gfc_conv_loop_setup (&loop
);
2948 /* Setup the gfc_se structures. */
2949 gfc_copy_loopinfo_to_se (&lse
, &loop
);
2950 gfc_copy_loopinfo_to_se (&rse
, &loop
);
2953 gfc_mark_ss_chain_used (rss
, 1);
2954 if (loop
.temp_ss
== NULL
)
2957 gfc_mark_ss_chain_used (lss
, 1);
2961 lse
.ss
= loop
.temp_ss
;
2962 gfc_mark_ss_chain_used (lss
, 3);
2963 gfc_mark_ss_chain_used (loop
.temp_ss
, 3);
2966 /* Start the scalarized loop body. */
2967 gfc_start_scalarized_body (&loop
, &body
);
2969 /* Translate the expression. */
2970 gfc_conv_expr (&rse
, expr2
);
2971 if (lss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
)
2973 gfc_conv_tmp_array_ref (&lse
);
2974 gfc_advance_se_ss_chain (&lse
);
2977 gfc_conv_expr (&lse
, expr1
);
2979 /* Form the mask expression according to the mask. */
2981 maskexpr
= gfc_build_array_ref (mask
, index
);
2983 maskexpr
= fold_build1 (TRUTH_NOT_EXPR
, TREE_TYPE (maskexpr
), maskexpr
);
2985 /* Use the scalar assignment as is. */
2986 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
,
2987 loop
.temp_ss
!= NULL
, false);
2988 tmp
= build3_v (COND_EXPR
, maskexpr
, tmp
, build_empty_stmt ());
2990 gfc_add_expr_to_block (&body
, tmp
);
2992 if (lss
== gfc_ss_terminator
)
2994 /* Increment count1. */
2995 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
2996 count1
, gfc_index_one_node
);
2997 gfc_add_modify_expr (&body
, count1
, tmp
);
2999 /* Use the scalar assignment as is. */
3000 gfc_add_block_to_block (&block
, &body
);
3004 gcc_assert (lse
.ss
== gfc_ss_terminator
3005 && rse
.ss
== gfc_ss_terminator
);
3007 if (loop
.temp_ss
!= NULL
)
3009 /* Increment count1 before finish the main body of a scalarized
3011 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
3012 count1
, gfc_index_one_node
);
3013 gfc_add_modify_expr (&body
, count1
, tmp
);
3014 gfc_trans_scalarized_loop_boundary (&loop
, &body
);
3016 /* We need to copy the temporary to the actual lhs. */
3017 gfc_init_se (&lse
, NULL
);
3018 gfc_init_se (&rse
, NULL
);
3019 gfc_copy_loopinfo_to_se (&lse
, &loop
);
3020 gfc_copy_loopinfo_to_se (&rse
, &loop
);
3022 rse
.ss
= loop
.temp_ss
;
3025 gfc_conv_tmp_array_ref (&rse
);
3026 gfc_advance_se_ss_chain (&rse
);
3027 gfc_conv_expr (&lse
, expr1
);
3029 gcc_assert (lse
.ss
== gfc_ss_terminator
3030 && rse
.ss
== gfc_ss_terminator
);
3032 /* Form the mask expression according to the mask tree list. */
3034 maskexpr
= gfc_build_array_ref (mask
, index
);
3036 maskexpr
= fold_build1 (TRUTH_NOT_EXPR
, TREE_TYPE (maskexpr
),
3039 /* Use the scalar assignment as is. */
3040 tmp
= gfc_trans_scalar_assign (&lse
, &rse
, expr1
->ts
, false, false);
3041 tmp
= build3_v (COND_EXPR
, maskexpr
, tmp
, build_empty_stmt ());
3042 gfc_add_expr_to_block (&body
, tmp
);
3044 /* Increment count2. */
3045 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
3046 count2
, gfc_index_one_node
);
3047 gfc_add_modify_expr (&body
, count2
, tmp
);
3051 /* Increment count1. */
3052 tmp
= fold_build2 (PLUS_EXPR
, gfc_array_index_type
,
3053 count1
, gfc_index_one_node
);
3054 gfc_add_modify_expr (&body
, count1
, tmp
);
3057 /* Generate the copying loops. */
3058 gfc_trans_scalarizing_loops (&loop
, &body
);
3060 /* Wrap the whole thing up. */
3061 gfc_add_block_to_block (&block
, &loop
.pre
);
3062 gfc_add_block_to_block (&block
, &loop
.post
);
3063 gfc_cleanup_loop (&loop
);
3066 return gfc_finish_block (&block
);
3070 /* Translate the WHERE construct or statement.
3071 This function can be called iteratively to translate the nested WHERE
3072 construct or statement.
3073 MASK is the control mask. */
3076 gfc_trans_where_2 (gfc_code
* code
, tree mask
, bool invert
,
3077 forall_info
* nested_forall_info
, stmtblock_t
* block
)
3079 stmtblock_t inner_size_body
;
3080 tree inner_size
, size
;
3088 tree count1
, count2
;
3092 tree pcmask
= NULL_TREE
;
3093 tree ppmask
= NULL_TREE
;
3094 tree cmask
= NULL_TREE
;
3095 tree pmask
= NULL_TREE
;
3097 /* the WHERE statement or the WHERE construct statement. */
3098 cblock
= code
->block
;
3100 /* As the mask array can be very big, prefer compact boolean types. */
3101 mask_type
= gfc_get_logical_type (gfc_logical_kinds
[0].kind
);
3103 /* Determine which temporary masks are needed. */
3106 /* One clause: No ELSEWHEREs. */
3107 need_cmask
= (cblock
->next
!= 0);
3110 else if (cblock
->block
->block
)
3112 /* Three or more clauses: Conditional ELSEWHEREs. */
3116 else if (cblock
->next
)
3118 /* Two clauses, the first non-empty. */
3120 need_pmask
= (mask
!= NULL_TREE
3121 && cblock
->block
->next
!= 0);
3123 else if (!cblock
->block
->next
)
3125 /* Two clauses, both empty. */
3129 /* Two clauses, the first empty, the second non-empty. */
3132 need_cmask
= (cblock
->block
->expr
!= 0);
3141 if (need_cmask
|| need_pmask
)
3143 /* Calculate the size of temporary needed by the mask-expr. */
3144 gfc_init_block (&inner_size_body
);
3145 inner_size
= compute_inner_temp_size (cblock
->expr
, cblock
->expr
,
3146 &inner_size_body
, &lss
, &rss
);
3148 /* Calculate the total size of temporary needed. */
3149 size
= compute_overall_iter_number (nested_forall_info
, inner_size
,
3150 &inner_size_body
, block
);
3152 /* Allocate temporary for WHERE mask if needed. */
3154 cmask
= allocate_temp_for_forall_nest_1 (mask_type
, size
, block
,
3157 /* Allocate temporary for !mask if needed. */
3159 pmask
= allocate_temp_for_forall_nest_1 (mask_type
, size
, block
,
3165 /* Each time around this loop, the where clause is conditional
3166 on the value of mask and invert, which are updated at the
3167 bottom of the loop. */
3169 /* Has mask-expr. */
3172 /* Ensure that the WHERE mask will be evaluated exactly once.
3173 If there are no statements in this WHERE/ELSEWHERE clause,
3174 then we don't need to update the control mask (cmask).
3175 If this is the last clause of the WHERE construct, then
3176 we don't need to update the pending control mask (pmask). */
3178 gfc_evaluate_where_mask (cblock
->expr
, nested_forall_info
,
3180 cblock
->next
? cmask
: NULL_TREE
,
3181 cblock
->block
? pmask
: NULL_TREE
,
3184 gfc_evaluate_where_mask (cblock
->expr
, nested_forall_info
,
3186 (cblock
->next
|| cblock
->block
)
3187 ? cmask
: NULL_TREE
,
3188 NULL_TREE
, mask_type
, block
);
3192 /* It's a final elsewhere-stmt. No mask-expr is present. */
3196 /* The body of this where clause are controlled by cmask with
3197 sense specified by invert. */
3199 /* Get the assignment statement of a WHERE statement, or the first
3200 statement in where-body-construct of a WHERE construct. */
3201 cnext
= cblock
->next
;
3206 /* WHERE assignment statement. */
3208 expr1
= cnext
->expr
;
3209 expr2
= cnext
->expr2
;
3210 if (nested_forall_info
!= NULL
)
3212 need_temp
= gfc_check_dependency (expr1
, expr2
, 0);
3214 gfc_trans_assign_need_temp (expr1
, expr2
,
3216 nested_forall_info
, block
);
3219 /* Variables to control maskexpr. */
3220 count1
= gfc_create_var (gfc_array_index_type
, "count1");
3221 count2
= gfc_create_var (gfc_array_index_type
, "count2");
3222 gfc_add_modify_expr (block
, count1
, gfc_index_zero_node
);
3223 gfc_add_modify_expr (block
, count2
, gfc_index_zero_node
);
3225 tmp
= gfc_trans_where_assign (expr1
, expr2
,
3229 tmp
= gfc_trans_nested_forall_loop (nested_forall_info
,
3231 gfc_add_expr_to_block (block
, tmp
);
3236 /* Variables to control maskexpr. */
3237 count1
= gfc_create_var (gfc_array_index_type
, "count1");
3238 count2
= gfc_create_var (gfc_array_index_type
, "count2");
3239 gfc_add_modify_expr (block
, count1
, gfc_index_zero_node
);
3240 gfc_add_modify_expr (block
, count2
, gfc_index_zero_node
);
3242 tmp
= gfc_trans_where_assign (expr1
, expr2
,
3245 gfc_add_expr_to_block (block
, tmp
);
3250 /* WHERE or WHERE construct is part of a where-body-construct. */
3252 gfc_trans_where_2 (cnext
, cmask
, invert
,
3253 nested_forall_info
, block
);
3260 /* The next statement within the same where-body-construct. */
3261 cnext
= cnext
->next
;
3263 /* The next masked-elsewhere-stmt, elsewhere-stmt, or end-where-stmt. */
3264 cblock
= cblock
->block
;
3265 if (mask
== NULL_TREE
)
3267 /* If we're the initial WHERE, we can simply invert the sense
3268 of the current mask to obtain the "mask" for the remaining
3275 /* Otherwise, for nested WHERE's we need to use the pending mask. */
3281 /* If we allocated a pending mask array, deallocate it now. */
3284 tree args
= gfc_chainon_list (NULL_TREE
, ppmask
);
3285 tmp
= build_function_call_expr (gfor_fndecl_internal_free
, args
);
3286 gfc_add_expr_to_block (block
, tmp
);
3289 /* If we allocated a current mask array, deallocate it now. */
3292 tree args
= gfc_chainon_list (NULL_TREE
, pcmask
);
3293 tmp
= build_function_call_expr (gfor_fndecl_internal_free
, args
);
3294 gfc_add_expr_to_block (block
, tmp
);
3298 /* Translate a simple WHERE construct or statement without dependencies.
3299 CBLOCK is the "then" clause of the WHERE statement, where CBLOCK->EXPR
3300 is the mask condition, and EBLOCK if non-NULL is the "else" clause.
3301 Currently both CBLOCK and EBLOCK are restricted to single assignments. */
3304 gfc_trans_where_3 (gfc_code
* cblock
, gfc_code
* eblock
)
3306 stmtblock_t block
, body
;
3307 gfc_expr
*cond
, *tdst
, *tsrc
, *edst
, *esrc
;
3308 tree tmp
, cexpr
, tstmt
, estmt
;
3309 gfc_ss
*css
, *tdss
, *tsss
;
3310 gfc_se cse
, tdse
, tsse
, edse
, esse
;
3315 cond
= cblock
->expr
;
3316 tdst
= cblock
->next
->expr
;
3317 tsrc
= cblock
->next
->expr2
;
3318 edst
= eblock
? eblock
->next
->expr
: NULL
;
3319 esrc
= eblock
? eblock
->next
->expr2
: NULL
;
3321 gfc_start_block (&block
);
3322 gfc_init_loopinfo (&loop
);
3324 /* Handle the condition. */
3325 gfc_init_se (&cse
, NULL
);
3326 css
= gfc_walk_expr (cond
);
3327 gfc_add_ss_to_loop (&loop
, css
);
3329 /* Handle the then-clause. */
3330 gfc_init_se (&tdse
, NULL
);
3331 gfc_init_se (&tsse
, NULL
);
3332 tdss
= gfc_walk_expr (tdst
);
3333 tsss
= gfc_walk_expr (tsrc
);
3334 if (tsss
== gfc_ss_terminator
)
3336 tsss
= gfc_get_ss ();
3337 tsss
->next
= gfc_ss_terminator
;
3338 tsss
->type
= GFC_SS_SCALAR
;
3341 gfc_add_ss_to_loop (&loop
, tdss
);
3342 gfc_add_ss_to_loop (&loop
, tsss
);
3346 /* Handle the else clause. */
3347 gfc_init_se (&edse
, NULL
);
3348 gfc_init_se (&esse
, NULL
);
3349 edss
= gfc_walk_expr (edst
);
3350 esss
= gfc_walk_expr (esrc
);
3351 if (esss
== gfc_ss_terminator
)
3353 esss
= gfc_get_ss ();
3354 esss
->next
= gfc_ss_terminator
;
3355 esss
->type
= GFC_SS_SCALAR
;
3358 gfc_add_ss_to_loop (&loop
, edss
);
3359 gfc_add_ss_to_loop (&loop
, esss
);
3362 gfc_conv_ss_startstride (&loop
);
3363 gfc_conv_loop_setup (&loop
);
3365 gfc_mark_ss_chain_used (css
, 1);
3366 gfc_mark_ss_chain_used (tdss
, 1);
3367 gfc_mark_ss_chain_used (tsss
, 1);
3370 gfc_mark_ss_chain_used (edss
, 1);
3371 gfc_mark_ss_chain_used (esss
, 1);
3374 gfc_start_scalarized_body (&loop
, &body
);
3376 gfc_copy_loopinfo_to_se (&cse
, &loop
);
3377 gfc_copy_loopinfo_to_se (&tdse
, &loop
);
3378 gfc_copy_loopinfo_to_se (&tsse
, &loop
);
3384 gfc_copy_loopinfo_to_se (&edse
, &loop
);
3385 gfc_copy_loopinfo_to_se (&esse
, &loop
);
3390 gfc_conv_expr (&cse
, cond
);
3391 gfc_add_block_to_block (&body
, &cse
.pre
);
3394 gfc_conv_expr (&tsse
, tsrc
);
3395 if (tdss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
)
3397 gfc_conv_tmp_array_ref (&tdse
);
3398 gfc_advance_se_ss_chain (&tdse
);
3401 gfc_conv_expr (&tdse
, tdst
);
3405 gfc_conv_expr (&esse
, esrc
);
3406 if (edss
!= gfc_ss_terminator
&& loop
.temp_ss
!= NULL
)
3408 gfc_conv_tmp_array_ref (&edse
);
3409 gfc_advance_se_ss_chain (&edse
);
3412 gfc_conv_expr (&edse
, edst
);
3415 tstmt
= gfc_trans_scalar_assign (&tdse
, &tsse
, tdst
->ts
, false, false);
3416 estmt
= eblock
? gfc_trans_scalar_assign (&edse
, &esse
, edst
->ts
, false, false)
3417 : build_empty_stmt ();
3418 tmp
= build3_v (COND_EXPR
, cexpr
, tstmt
, estmt
);
3419 gfc_add_expr_to_block (&body
, tmp
);
3420 gfc_add_block_to_block (&body
, &cse
.post
);
3422 gfc_trans_scalarizing_loops (&loop
, &body
);
3423 gfc_add_block_to_block (&block
, &loop
.pre
);
3424 gfc_add_block_to_block (&block
, &loop
.post
);
3425 gfc_cleanup_loop (&loop
);
3427 return gfc_finish_block (&block
);
3430 /* As the WHERE or WHERE construct statement can be nested, we call
3431 gfc_trans_where_2 to do the translation, and pass the initial
3432 NULL values for both the control mask and the pending control mask. */
3435 gfc_trans_where (gfc_code
* code
)
3441 cblock
= code
->block
;
3443 && cblock
->next
->op
== EXEC_ASSIGN
3444 && !cblock
->next
->next
)
3446 eblock
= cblock
->block
;
3449 /* A simple "WHERE (cond) x = y" statement or block is
3450 dependence free if cond is not dependent upon writing x,
3451 and the source y is unaffected by the destination x. */
3452 if (!gfc_check_dependency (cblock
->next
->expr
,
3454 && !gfc_check_dependency (cblock
->next
->expr
,
3455 cblock
->next
->expr2
, 0))
3456 return gfc_trans_where_3 (cblock
, NULL
);
3458 else if (!eblock
->expr
3461 && eblock
->next
->op
== EXEC_ASSIGN
3462 && !eblock
->next
->next
)
3464 /* A simple "WHERE (cond) x1 = y1 ELSEWHERE x2 = y2 ENDWHERE"
3465 block is dependence free if cond is not dependent on writes
3466 to x1 and x2, y1 is not dependent on writes to x2, and y2
3467 is not dependent on writes to x1, and both y's are not
3468 dependent upon their own x's. */
3469 if (!gfc_check_dependency(cblock
->next
->expr
,
3471 && !gfc_check_dependency(eblock
->next
->expr
,
3473 && !gfc_check_dependency(cblock
->next
->expr
,
3474 eblock
->next
->expr2
, 0)
3475 && !gfc_check_dependency(eblock
->next
->expr
,
3476 cblock
->next
->expr2
, 0)
3477 && !gfc_check_dependency(cblock
->next
->expr
,
3478 cblock
->next
->expr2
, 0)
3479 && !gfc_check_dependency(eblock
->next
->expr
,
3480 eblock
->next
->expr2
, 0))
3481 return gfc_trans_where_3 (cblock
, eblock
);
3485 gfc_start_block (&block
);
3487 gfc_trans_where_2 (code
, NULL
, false, NULL
, &block
);
3489 return gfc_finish_block (&block
);
3493 /* CYCLE a DO loop. The label decl has already been created by
3494 gfc_trans_do(), it's in TREE_PURPOSE (backend_decl) of the gfc_code
3495 node at the head of the loop. We must mark the label as used. */
3498 gfc_trans_cycle (gfc_code
* code
)
3502 cycle_label
= TREE_PURPOSE (code
->ext
.whichloop
->backend_decl
);
3503 TREE_USED (cycle_label
) = 1;
3504 return build1_v (GOTO_EXPR
, cycle_label
);
3508 /* EXIT a DO loop. Similar to CYCLE, but now the label is in
3509 TREE_VALUE (backend_decl) of the gfc_code node at the head of the
3513 gfc_trans_exit (gfc_code
* code
)
3517 exit_label
= TREE_VALUE (code
->ext
.whichloop
->backend_decl
);
3518 TREE_USED (exit_label
) = 1;
3519 return build1_v (GOTO_EXPR
, exit_label
);
3523 /* Translate the ALLOCATE statement. */
3526 gfc_trans_allocate (gfc_code
* code
)
3538 if (!code
->ext
.alloc_list
)
3541 gfc_start_block (&block
);
3545 tree gfc_int4_type_node
= gfc_get_int_type (4);
3547 stat
= gfc_create_var (gfc_int4_type_node
, "stat");
3548 pstat
= build_fold_addr_expr (stat
);
3550 error_label
= gfc_build_label_decl (NULL_TREE
);
3551 TREE_USED (error_label
) = 1;
3555 pstat
= integer_zero_node
;
3556 stat
= error_label
= NULL_TREE
;
3560 for (al
= code
->ext
.alloc_list
; al
!= NULL
; al
= al
->next
)
3564 gfc_init_se (&se
, NULL
);
3565 gfc_start_block (&se
.pre
);
3567 se
.want_pointer
= 1;
3568 se
.descriptor_only
= 1;
3569 gfc_conv_expr (&se
, expr
);
3571 if (!gfc_array_allocate (&se
, expr
, pstat
))
3573 /* A scalar or derived type. */
3574 tmp
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se
.expr
)));
3576 if (expr
->ts
.type
== BT_CHARACTER
&& tmp
== NULL_TREE
)
3577 tmp
= se
.string_length
;
3579 parm
= gfc_chainon_list (NULL_TREE
, tmp
);
3580 parm
= gfc_chainon_list (parm
, pstat
);
3581 tmp
= build_function_call_expr (gfor_fndecl_allocate
, parm
);
3582 tmp
= build2 (MODIFY_EXPR
, void_type_node
, se
.expr
, tmp
);
3583 gfc_add_expr_to_block (&se
.pre
, tmp
);
3587 tmp
= build1_v (GOTO_EXPR
, error_label
);
3588 parm
= fold_build2 (NE_EXPR
, boolean_type_node
,
3589 stat
, build_int_cst (TREE_TYPE (stat
), 0));
3590 tmp
= fold_build3 (COND_EXPR
, void_type_node
,
3591 parm
, tmp
, build_empty_stmt ());
3592 gfc_add_expr_to_block (&se
.pre
, tmp
);
3595 if (expr
->ts
.type
== BT_DERIVED
&& expr
->ts
.derived
->attr
.alloc_comp
)
3597 tmp
= build_fold_indirect_ref (se
.expr
);
3598 tmp
= gfc_nullify_alloc_comp (expr
->ts
.derived
, tmp
, 0);
3599 gfc_add_expr_to_block (&se
.pre
, tmp
);
3604 tmp
= gfc_finish_block (&se
.pre
);
3605 gfc_add_expr_to_block (&block
, tmp
);
3608 /* Assign the value to the status variable. */
3611 tmp
= build1_v (LABEL_EXPR
, error_label
);
3612 gfc_add_expr_to_block (&block
, tmp
);
3614 gfc_init_se (&se
, NULL
);
3615 gfc_conv_expr_lhs (&se
, code
->expr
);
3616 tmp
= convert (TREE_TYPE (se
.expr
), stat
);
3617 gfc_add_modify_expr (&block
, se
.expr
, tmp
);
3620 return gfc_finish_block (&block
);
3624 /* Translate a DEALLOCATE statement.
3625 There are two cases within the for loop:
3626 (1) deallocate(a1, a2, a3) is translated into the following sequence
3627 _gfortran_deallocate(a1, 0B)
3628 _gfortran_deallocate(a2, 0B)
3629 _gfortran_deallocate(a3, 0B)
3630 where the STAT= variable is passed a NULL pointer.
3631 (2) deallocate(a1, a2, a3, stat=i) is translated into the following
3633 _gfortran_deallocate(a1, &stat)
3634 astat = astat + stat
3635 _gfortran_deallocate(a2, &stat)
3636 astat = astat + stat
3637 _gfortran_deallocate(a3, &stat)
3638 astat = astat + stat
3639 In case (1), we simply return at the end of the for loop. In case (2)
3640 we set STAT= astat. */
3642 gfc_trans_deallocate (gfc_code
* code
)
3647 tree apstat
, astat
, parm
, pstat
, stat
, tmp
;
3650 gfc_start_block (&block
);
3652 /* Set up the optional STAT= */
3655 tree gfc_int4_type_node
= gfc_get_int_type (4);
3657 /* Variable used with the library call. */
3658 stat
= gfc_create_var (gfc_int4_type_node
, "stat");
3659 pstat
= build_fold_addr_expr (stat
);
3661 /* Running total of possible deallocation failures. */
3662 astat
= gfc_create_var (gfc_int4_type_node
, "astat");
3663 apstat
= build_fold_addr_expr (astat
);
3665 /* Initialize astat to 0. */
3666 gfc_add_modify_expr (&block
, astat
, build_int_cst (TREE_TYPE (astat
), 0));
3670 pstat
= apstat
= null_pointer_node
;
3671 stat
= astat
= NULL_TREE
;
3674 for (al
= code
->ext
.alloc_list
; al
!= NULL
; al
= al
->next
)
3677 gcc_assert (expr
->expr_type
== EXPR_VARIABLE
);
3679 gfc_init_se (&se
, NULL
);
3680 gfc_start_block (&se
.pre
);
3682 se
.want_pointer
= 1;
3683 se
.descriptor_only
= 1;
3684 gfc_conv_expr (&se
, expr
);
3686 if (expr
->ts
.type
== BT_DERIVED
3687 && expr
->ts
.derived
->attr
.alloc_comp
)
3690 gfc_ref
*last
= NULL
;
3691 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
3692 if (ref
->type
== REF_COMPONENT
)
3695 /* Do not deallocate the components of a derived type
3696 ultimate pointer component. */
3697 if (!(last
&& last
->u
.c
.component
->pointer
)
3698 && !(!last
&& expr
->symtree
->n
.sym
->attr
.pointer
))
3700 tmp
= gfc_deallocate_alloc_comp (expr
->ts
.derived
, se
.expr
,
3702 gfc_add_expr_to_block (&se
.pre
, tmp
);
3707 tmp
= gfc_array_deallocate (se
.expr
, pstat
);
3710 parm
= gfc_chainon_list (NULL_TREE
, se
.expr
);
3711 parm
= gfc_chainon_list (parm
, pstat
);
3712 tmp
= build_function_call_expr (gfor_fndecl_deallocate
, parm
);
3713 gfc_add_expr_to_block (&se
.pre
, tmp
);
3715 tmp
= build2 (MODIFY_EXPR
, void_type_node
,
3716 se
.expr
, build_int_cst (TREE_TYPE (se
.expr
), 0));
3719 gfc_add_expr_to_block (&se
.pre
, tmp
);
3721 /* Keep track of the number of failed deallocations by adding stat
3722 of the last deallocation to the running total. */
3725 apstat
= build2 (PLUS_EXPR
, TREE_TYPE (stat
), astat
, stat
);
3726 gfc_add_modify_expr (&se
.pre
, astat
, apstat
);
3729 tmp
= gfc_finish_block (&se
.pre
);
3730 gfc_add_expr_to_block (&block
, tmp
);
3734 /* Assign the value to the status variable. */
3737 gfc_init_se (&se
, NULL
);
3738 gfc_conv_expr_lhs (&se
, code
->expr
);
3739 tmp
= convert (TREE_TYPE (se
.expr
), astat
);
3740 gfc_add_modify_expr (&block
, se
.expr
, tmp
);
3743 return gfc_finish_block (&block
);