1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2013 Free Software Foundation, Inc.
3 Contributed by Thomas König.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
27 #include "dependency.h"
28 #include "constructor.h"
31 /* Forward declarations. */
33 static void strip_function_call (gfc_expr
*);
34 static void optimize_namespace (gfc_namespace
*);
35 static void optimize_assignment (gfc_code
*);
36 static bool optimize_op (gfc_expr
*);
37 static bool optimize_comparison (gfc_expr
*, gfc_intrinsic_op
);
38 static bool optimize_trim (gfc_expr
*);
39 static bool optimize_lexical_comparison (gfc_expr
*);
40 static void optimize_minmaxloc (gfc_expr
**);
41 static bool is_empty_string (gfc_expr
*e
);
42 static void doloop_warn (gfc_namespace
*);
43 static void optimize_reduction (gfc_namespace
*);
44 static int callback_reduction (gfc_expr
**, int *, void *);
46 /* How deep we are inside an argument list. */
48 static int count_arglist
;
50 /* Pointer to an array of gfc_expr ** we operate on, plus its size
53 static gfc_expr
***expr_array
;
54 static int expr_size
, expr_count
;
56 /* Pointer to the gfc_code we currently work on - to be able to insert
57 a block before the statement. */
59 static gfc_code
**current_code
;
61 /* Pointer to the block to be inserted, and the statement we are
62 changing within the block. */
64 static gfc_code
*inserted_block
, **changed_statement
;
66 /* The namespace we are currently dealing with. */
68 static gfc_namespace
*current_ns
;
70 /* If we are within any forall loop. */
72 static int forall_level
;
74 /* Keep track of whether we are within an OMP workshare. */
76 static bool in_omp_workshare
;
78 /* Keep track of iterators for array constructors. */
80 static int iterator_level
;
82 /* Keep track of DO loop levels. */
84 static gfc_code
**doloop_list
;
85 static int doloop_size
, doloop_level
;
87 /* Vector of gfc_expr * to keep track of DO loops. */
89 struct my_struct
*evec
;
91 /* Entry point - run all passes for a namespace. */
94 gfc_run_passes (gfc_namespace
*ns
)
97 /* Warn about dubious DO loops where the index might
102 doloop_list
= XNEWVEC(gfc_code
*, doloop_size
);
104 XDELETEVEC (doloop_list
);
106 if (gfc_option
.flag_frontend_optimize
)
109 expr_array
= XNEWVEC(gfc_expr
**, expr_size
);
111 optimize_namespace (ns
);
112 optimize_reduction (ns
);
113 if (gfc_option
.dump_fortran_optimized
)
114 gfc_dump_parse_tree (ns
, stdout
);
116 XDELETEVEC (expr_array
);
120 /* Callback for each gfc_code node invoked through gfc_code_walker
121 from optimize_namespace. */
124 optimize_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
125 void *data ATTRIBUTE_UNUSED
)
132 if (op
== EXEC_CALL
|| op
== EXEC_COMPCALL
|| op
== EXEC_ASSIGN_CALL
133 || op
== EXEC_CALL_PPC
)
139 inserted_block
= NULL
;
140 changed_statement
= NULL
;
142 if (op
== EXEC_ASSIGN
)
143 optimize_assignment (*c
);
147 /* Callback for each gfc_expr node invoked through gfc_code_walker
148 from optimize_namespace. */
151 optimize_expr (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
152 void *data ATTRIBUTE_UNUSED
)
156 if ((*e
)->expr_type
== EXPR_FUNCTION
)
159 function_expr
= true;
162 function_expr
= false;
164 if (optimize_trim (*e
))
165 gfc_simplify_expr (*e
, 0);
167 if (optimize_lexical_comparison (*e
))
168 gfc_simplify_expr (*e
, 0);
170 if ((*e
)->expr_type
== EXPR_OP
&& optimize_op (*e
))
171 gfc_simplify_expr (*e
, 0);
173 if ((*e
)->expr_type
== EXPR_FUNCTION
&& (*e
)->value
.function
.isym
)
174 switch ((*e
)->value
.function
.isym
->id
)
176 case GFC_ISYM_MINLOC
:
177 case GFC_ISYM_MAXLOC
:
178 optimize_minmaxloc (e
);
190 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
191 function is a scalar, just copy it; otherwise returns the new element, the
192 old one can be freed. */
195 copy_walk_reduction_arg (gfc_constructor
*c
, gfc_expr
*fn
)
197 gfc_expr
*fcn
, *e
= c
->expr
;
199 fcn
= gfc_copy_expr (e
);
202 gfc_constructor_base newbase
;
204 gfc_constructor
*new_c
;
207 new_expr
= gfc_get_expr ();
208 new_expr
->expr_type
= EXPR_ARRAY
;
209 new_expr
->ts
= e
->ts
;
210 new_expr
->where
= e
->where
;
212 new_c
= gfc_constructor_append_expr (&newbase
, fcn
, &(e
->where
));
213 new_c
->iterator
= c
->iterator
;
214 new_expr
->value
.constructor
= newbase
;
222 gfc_isym_id id
= fn
->value
.function
.isym
->id
;
224 if (id
== GFC_ISYM_SUM
|| id
== GFC_ISYM_PRODUCT
)
225 fcn
= gfc_build_intrinsic_call (current_ns
, id
,
226 fn
->value
.function
.isym
->name
,
227 fn
->where
, 3, fcn
, NULL
, NULL
);
228 else if (id
== GFC_ISYM_ANY
|| id
== GFC_ISYM_ALL
)
229 fcn
= gfc_build_intrinsic_call (current_ns
, id
,
230 fn
->value
.function
.isym
->name
,
231 fn
->where
, 2, fcn
, NULL
);
233 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
235 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
241 /* Callback function for optimzation of reductions to scalars. Transform ANY
242 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
243 correspondingly. Handly only the simple cases without MASK and DIM. */
246 callback_reduction (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
247 void *data ATTRIBUTE_UNUSED
)
252 gfc_actual_arglist
*a
;
253 gfc_actual_arglist
*dim
;
255 gfc_expr
*res
, *new_expr
;
256 gfc_actual_arglist
*mask
;
260 if (fn
->rank
!= 0 || fn
->expr_type
!= EXPR_FUNCTION
261 || fn
->value
.function
.isym
== NULL
)
264 id
= fn
->value
.function
.isym
->id
;
266 if (id
!= GFC_ISYM_SUM
&& id
!= GFC_ISYM_PRODUCT
267 && id
!= GFC_ISYM_ANY
&& id
!= GFC_ISYM_ALL
)
270 a
= fn
->value
.function
.actual
;
272 /* Don't handle MASK or DIM. */
276 if (dim
->expr
!= NULL
)
279 if (id
== GFC_ISYM_SUM
|| id
== GFC_ISYM_PRODUCT
)
282 if ( mask
->expr
!= NULL
)
288 if (arg
->expr_type
!= EXPR_ARRAY
)
297 case GFC_ISYM_PRODUCT
:
298 op
= INTRINSIC_TIMES
;
313 c
= gfc_constructor_first (arg
->value
.constructor
);
315 /* Don't do any simplififcation if we have
316 - no element in the constructor or
317 - only have a single element in the array which contains an
323 res
= copy_walk_reduction_arg (c
, fn
);
325 c
= gfc_constructor_next (c
);
328 new_expr
= gfc_get_expr ();
329 new_expr
->ts
= fn
->ts
;
330 new_expr
->expr_type
= EXPR_OP
;
331 new_expr
->rank
= fn
->rank
;
332 new_expr
->where
= fn
->where
;
333 new_expr
->value
.op
.op
= op
;
334 new_expr
->value
.op
.op1
= res
;
335 new_expr
->value
.op
.op2
= copy_walk_reduction_arg (c
, fn
);
337 c
= gfc_constructor_next (c
);
340 gfc_simplify_expr (res
, 0);
347 /* Callback function for common function elimination, called from cfe_expr_0.
348 Put all eligible function expressions into expr_array. */
351 cfe_register_funcs (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
352 void *data ATTRIBUTE_UNUSED
)
355 if ((*e
)->expr_type
!= EXPR_FUNCTION
)
358 /* We don't do character functions with unknown charlens. */
359 if ((*e
)->ts
.type
== BT_CHARACTER
360 && ((*e
)->ts
.u
.cl
== NULL
|| (*e
)->ts
.u
.cl
->length
== NULL
361 || (*e
)->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
))
364 /* We don't do function elimination within FORALL statements, it can
365 lead to wrong-code in certain circumstances. */
367 if (forall_level
> 0)
370 /* Function elimination inside an iterator could lead to functions which
371 depend on iterator variables being moved outside. FIXME: We should check
372 if the functions do indeed depend on the iterator variable. */
374 if (iterator_level
> 0)
377 /* If we don't know the shape at compile time, we create an allocatable
378 temporary variable to hold the intermediate result, but only if
379 allocation on assignment is active. */
381 if ((*e
)->rank
> 0 && (*e
)->shape
== NULL
&& !gfc_option
.flag_realloc_lhs
)
384 /* Skip the test for pure functions if -faggressive-function-elimination
386 if ((*e
)->value
.function
.esym
)
388 /* Don't create an array temporary for elemental functions. */
389 if ((*e
)->value
.function
.esym
->attr
.elemental
&& (*e
)->rank
> 0)
392 /* Only eliminate potentially impure functions if the
393 user specifically requested it. */
394 if (!gfc_option
.flag_aggressive_function_elimination
395 && !(*e
)->value
.function
.esym
->attr
.pure
396 && !(*e
)->value
.function
.esym
->attr
.implicit_pure
)
400 if ((*e
)->value
.function
.isym
)
402 /* Conversions are handled on the fly by the middle end,
403 transpose during trans-* stages and TRANSFER by the middle end. */
404 if ((*e
)->value
.function
.isym
->id
== GFC_ISYM_CONVERSION
405 || (*e
)->value
.function
.isym
->id
== GFC_ISYM_TRANSFER
406 || gfc_inline_intrinsic_function_p (*e
))
409 /* Don't create an array temporary for elemental functions,
410 as this would be wasteful of memory.
411 FIXME: Create a scalar temporary during scalarization. */
412 if ((*e
)->value
.function
.isym
->elemental
&& (*e
)->rank
> 0)
415 if (!(*e
)->value
.function
.isym
->pure
)
419 if (expr_count
>= expr_size
)
421 expr_size
+= expr_size
;
422 expr_array
= XRESIZEVEC(gfc_expr
**, expr_array
, expr_size
);
424 expr_array
[expr_count
] = e
;
429 /* Returns a new expression (a variable) to be used in place of the old one,
430 with an assignment statement before the current statement to set
431 the value of the variable. Creates a new BLOCK for the statement if
432 that hasn't already been done and puts the statement, plus the
433 newly created variables, in that block. */
436 create_var (gfc_expr
* e
)
438 char name
[GFC_MAX_SYMBOL_LEN
+1];
440 gfc_symtree
*symtree
;
447 /* If the block hasn't already been created, do so. */
448 if (inserted_block
== NULL
)
450 inserted_block
= XCNEW (gfc_code
);
451 inserted_block
->op
= EXEC_BLOCK
;
452 inserted_block
->loc
= (*current_code
)->loc
;
453 ns
= gfc_build_block_ns (current_ns
);
454 inserted_block
->ext
.block
.ns
= ns
;
455 inserted_block
->ext
.block
.assoc
= NULL
;
457 ns
->code
= *current_code
;
459 /* If the statement has a label, make sure it is transferred to
460 the newly created block. */
462 if ((*current_code
)->here
)
464 inserted_block
->here
= (*current_code
)->here
;
465 (*current_code
)->here
= NULL
;
468 inserted_block
->next
= (*current_code
)->next
;
469 changed_statement
= &(inserted_block
->ext
.block
.ns
->code
);
470 (*current_code
)->next
= NULL
;
471 /* Insert the BLOCK at the right position. */
472 *current_code
= inserted_block
;
473 ns
->parent
= current_ns
;
476 ns
= inserted_block
->ext
.block
.ns
;
478 sprintf(name
, "__var_%d",num
++);
479 if (gfc_get_sym_tree (name
, ns
, &symtree
, false) != 0)
482 symbol
= symtree
->n
.sym
;
487 symbol
->as
= gfc_get_array_spec ();
488 symbol
->as
->rank
= e
->rank
;
490 if (e
->shape
== NULL
)
492 /* We don't know the shape at compile time, so we use an
494 symbol
->as
->type
= AS_DEFERRED
;
495 symbol
->attr
.allocatable
= 1;
499 symbol
->as
->type
= AS_EXPLICIT
;
500 /* Copy the shape. */
501 for (i
=0; i
<e
->rank
; i
++)
505 p
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
507 mpz_set_si (p
->value
.integer
, 1);
508 symbol
->as
->lower
[i
] = p
;
510 q
= gfc_get_constant_expr (BT_INTEGER
, gfc_index_integer_kind
,
512 mpz_set (q
->value
.integer
, e
->shape
[i
]);
513 symbol
->as
->upper
[i
] = q
;
518 symbol
->attr
.flavor
= FL_VARIABLE
;
519 symbol
->attr
.referenced
= 1;
520 symbol
->attr
.dimension
= e
->rank
> 0;
521 gfc_commit_symbol (symbol
);
523 result
= gfc_get_expr ();
524 result
->expr_type
= EXPR_VARIABLE
;
526 result
->rank
= e
->rank
;
527 result
->shape
= gfc_copy_shape (e
->shape
, e
->rank
);
528 result
->symtree
= symtree
;
529 result
->where
= e
->where
;
532 result
->ref
= gfc_get_ref ();
533 result
->ref
->type
= REF_ARRAY
;
534 result
->ref
->u
.ar
.type
= AR_FULL
;
535 result
->ref
->u
.ar
.where
= e
->where
;
536 result
->ref
->u
.ar
.as
= symbol
->ts
.type
== BT_CLASS
537 ? CLASS_DATA (symbol
)->as
: symbol
->as
;
538 if (gfc_option
.warn_array_temp
)
539 gfc_warning ("Creating array temporary at %L", &(e
->where
));
542 /* Generate the new assignment. */
543 n
= XCNEW (gfc_code
);
545 n
->loc
= (*current_code
)->loc
;
546 n
->next
= *changed_statement
;
547 n
->expr1
= gfc_copy_expr (result
);
549 *changed_statement
= n
;
554 /* Warn about function elimination. */
557 warn_function_elimination (gfc_expr
*e
)
559 if (e
->expr_type
!= EXPR_FUNCTION
)
561 if (e
->value
.function
.esym
)
562 gfc_warning ("Removing call to function '%s' at %L",
563 e
->value
.function
.esym
->name
, &(e
->where
));
564 else if (e
->value
.function
.isym
)
565 gfc_warning ("Removing call to function '%s' at %L",
566 e
->value
.function
.isym
->name
, &(e
->where
));
568 /* Callback function for the code walker for doing common function
569 elimination. This builds up the list of functions in the expression
570 and goes through them to detect duplicates, which it then replaces
574 cfe_expr_0 (gfc_expr
**e
, int *walk_subtrees
,
575 void *data ATTRIBUTE_UNUSED
)
580 /* Don't do this optimization within OMP workshare. */
582 if (in_omp_workshare
)
590 gfc_expr_walker (e
, cfe_register_funcs
, NULL
);
592 /* Walk through all the functions. */
594 for (i
=1; i
<expr_count
; i
++)
596 /* Skip if the function has been replaced by a variable already. */
597 if ((*(expr_array
[i
]))->expr_type
== EXPR_VARIABLE
)
603 if (gfc_dep_compare_functions (*(expr_array
[i
]),
604 *(expr_array
[j
]), true) == 0)
607 newvar
= create_var (*(expr_array
[i
]));
609 if (gfc_option
.warn_function_elimination
)
610 warn_function_elimination (*(expr_array
[j
]));
612 free (*(expr_array
[j
]));
613 *(expr_array
[j
]) = gfc_copy_expr (newvar
);
617 *(expr_array
[i
]) = newvar
;
620 /* We did all the necessary walking in this function. */
625 /* Callback function for common function elimination, called from
626 gfc_code_walker. This keeps track of the current code, in order
627 to insert statements as needed. */
630 cfe_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
631 void *data ATTRIBUTE_UNUSED
)
634 inserted_block
= NULL
;
635 changed_statement
= NULL
;
639 /* Dummy function for expression call back, for use when we
640 really don't want to do any walking. */
643 dummy_expr_callback (gfc_expr
**e ATTRIBUTE_UNUSED
, int *walk_subtrees
,
644 void *data ATTRIBUTE_UNUSED
)
650 /* Dummy function for code callback, for use when we really
651 don't want to do anything. */
653 dummy_code_callback (gfc_code
**e ATTRIBUTE_UNUSED
,
654 int *walk_subtrees ATTRIBUTE_UNUSED
,
655 void *data ATTRIBUTE_UNUSED
)
660 /* Code callback function for converting
667 This is because common function elimination would otherwise place the
668 temporary variables outside the loop. */
671 convert_do_while (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
672 void *data ATTRIBUTE_UNUSED
)
675 gfc_code
*c_if1
, *c_if2
, *c_exit
;
677 gfc_expr
*e_not
, *e_cond
;
679 if (co
->op
!= EXEC_DO_WHILE
)
682 if (co
->expr1
== NULL
|| co
->expr1
->expr_type
== EXPR_CONSTANT
)
687 /* Generate the condition of the if statement, which is .not. the original
689 e_not
= gfc_get_expr ();
690 e_not
->ts
= e_cond
->ts
;
691 e_not
->where
= e_cond
->where
;
692 e_not
->expr_type
= EXPR_OP
;
693 e_not
->value
.op
.op
= INTRINSIC_NOT
;
694 e_not
->value
.op
.op1
= e_cond
;
696 /* Generate the EXIT statement. */
697 c_exit
= XCNEW (gfc_code
);
698 c_exit
->op
= EXEC_EXIT
;
699 c_exit
->ext
.which_construct
= co
;
700 c_exit
->loc
= co
->loc
;
702 /* Generate the IF statement. */
703 c_if2
= XCNEW (gfc_code
);
705 c_if2
->expr1
= e_not
;
706 c_if2
->next
= c_exit
;
707 c_if2
->loc
= co
->loc
;
709 /* ... plus the one to chain it to. */
710 c_if1
= XCNEW (gfc_code
);
712 c_if1
->block
= c_if2
;
713 c_if1
->loc
= co
->loc
;
715 /* Make the DO WHILE loop into a DO block by replacing the condition
716 with a true constant. */
717 co
->expr1
= gfc_get_logical_expr (gfc_default_integer_kind
, &co
->loc
, true);
719 /* Hang the generated if statement into the loop body. */
721 loopblock
= co
->block
->next
;
722 co
->block
->next
= c_if1
;
723 c_if1
->next
= loopblock
;
728 /* Code callback function for converting
741 because otherwise common function elimination would place the BLOCKs
742 into the wrong place. */
745 convert_elseif (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
746 void *data ATTRIBUTE_UNUSED
)
749 gfc_code
*c_if1
, *c_if2
, *else_stmt
;
751 if (co
->op
!= EXEC_IF
)
754 /* This loop starts out with the first ELSE statement. */
755 else_stmt
= co
->block
->block
;
757 while (else_stmt
!= NULL
)
761 /* If there is no condition, we're done. */
762 if (else_stmt
->expr1
== NULL
)
765 next_else
= else_stmt
->block
;
767 /* Generate the new IF statement. */
768 c_if2
= XCNEW (gfc_code
);
770 c_if2
->expr1
= else_stmt
->expr1
;
771 c_if2
->next
= else_stmt
->next
;
772 c_if2
->loc
= else_stmt
->loc
;
773 c_if2
->block
= next_else
;
775 /* ... plus the one to chain it to. */
776 c_if1
= XCNEW (gfc_code
);
778 c_if1
->block
= c_if2
;
779 c_if1
->loc
= else_stmt
->loc
;
781 /* Insert the new IF after the ELSE. */
782 else_stmt
->expr1
= NULL
;
783 else_stmt
->next
= c_if1
;
784 else_stmt
->block
= NULL
;
786 else_stmt
= next_else
;
788 /* Don't walk subtrees. */
791 /* Optimize a namespace, including all contained namespaces. */
794 optimize_namespace (gfc_namespace
*ns
)
800 in_omp_workshare
= false;
802 gfc_code_walker (&ns
->code
, convert_do_while
, dummy_expr_callback
, NULL
);
803 gfc_code_walker (&ns
->code
, convert_elseif
, dummy_expr_callback
, NULL
);
804 gfc_code_walker (&ns
->code
, cfe_code
, cfe_expr_0
, NULL
);
805 gfc_code_walker (&ns
->code
, optimize_code
, optimize_expr
, NULL
);
807 /* BLOCKs are handled in the expression walker below. */
808 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
810 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
811 optimize_namespace (ns
);
816 optimize_reduction (gfc_namespace
*ns
)
819 gfc_code_walker (&ns
->code
, dummy_code_callback
, callback_reduction
, NULL
);
821 /* BLOCKs are handled in the expression walker below. */
822 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
824 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
825 optimize_reduction (ns
);
832 a = matmul(b,c) ; a = a + d
833 where the array function is not elemental and not allocatable
834 and does not depend on the left-hand side.
838 optimize_binop_array_assignment (gfc_code
*c
, gfc_expr
**rhs
, bool seen_op
)
843 if (e
->expr_type
== EXPR_OP
)
845 switch (e
->value
.op
.op
)
847 /* Unary operators and exponentiation: Only look at a single
850 case INTRINSIC_UPLUS
:
851 case INTRINSIC_UMINUS
:
852 case INTRINSIC_PARENTHESES
:
853 case INTRINSIC_POWER
:
854 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, seen_op
))
859 /* Binary operators. */
860 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, true))
863 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op2
, true))
869 else if (seen_op
&& e
->expr_type
== EXPR_FUNCTION
&& e
->rank
> 0
870 && ! (e
->value
.function
.esym
871 && (e
->value
.function
.esym
->attr
.elemental
872 || e
->value
.function
.esym
->attr
.allocatable
873 || e
->value
.function
.esym
->ts
.type
!= c
->expr1
->ts
.type
874 || e
->value
.function
.esym
->ts
.kind
!= c
->expr1
->ts
.kind
))
875 && ! (e
->value
.function
.isym
876 && (e
->value
.function
.isym
->elemental
877 || e
->ts
.type
!= c
->expr1
->ts
.type
878 || e
->ts
.kind
!= c
->expr1
->ts
.kind
))
879 && ! gfc_inline_intrinsic_function_p (e
))
885 /* Insert a new assignment statement after the current one. */
886 n
= XCNEW (gfc_code
);
892 n
->expr1
= gfc_copy_expr (c
->expr1
);
894 new_expr
= gfc_copy_expr (c
->expr1
);
902 /* Nothing to optimize. */
906 /* Remove unneeded TRIMs at the end of expressions. */
909 remove_trim (gfc_expr
*rhs
)
915 /* Check for a // b // trim(c). Looping is probably not
916 necessary because the parser usually generates
917 (// (// a b ) trim(c) ) , but better safe than sorry. */
919 while (rhs
->expr_type
== EXPR_OP
920 && rhs
->value
.op
.op
== INTRINSIC_CONCAT
)
921 rhs
= rhs
->value
.op
.op2
;
923 while (rhs
->expr_type
== EXPR_FUNCTION
&& rhs
->value
.function
.isym
924 && rhs
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
926 strip_function_call (rhs
);
927 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
935 /* Optimizations for an assignment. */
938 optimize_assignment (gfc_code
* c
)
945 if (lhs
->ts
.type
== BT_CHARACTER
&& !lhs
->ts
.deferred
)
947 /* Optimize a = trim(b) to a = b. */
950 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
951 if (is_empty_string (rhs
))
952 rhs
->value
.character
.length
= 0;
955 if (lhs
->rank
> 0 && gfc_check_dependency (lhs
, rhs
, true) == 0)
956 optimize_binop_array_assignment (c
, &rhs
, false);
960 /* Remove an unneeded function call, modifying the expression.
961 This replaces the function call with the value of its
962 first argument. The rest of the argument list is freed. */
965 strip_function_call (gfc_expr
*e
)
968 gfc_actual_arglist
*a
;
970 a
= e
->value
.function
.actual
;
972 /* We should have at least one argument. */
973 gcc_assert (a
->expr
!= NULL
);
977 /* Free the remaining arglist, if any. */
979 gfc_free_actual_arglist (a
->next
);
981 /* Graft the argument expression onto the original function. */
987 /* Optimization of lexical comparison functions. */
990 optimize_lexical_comparison (gfc_expr
*e
)
992 if (e
->expr_type
!= EXPR_FUNCTION
|| e
->value
.function
.isym
== NULL
)
995 switch (e
->value
.function
.isym
->id
)
998 return optimize_comparison (e
, INTRINSIC_LE
);
1001 return optimize_comparison (e
, INTRINSIC_GE
);
1004 return optimize_comparison (e
, INTRINSIC_GT
);
1007 return optimize_comparison (e
, INTRINSIC_LT
);
1015 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1016 do CHARACTER because of possible pessimization involving character
1020 combine_array_constructor (gfc_expr
*e
)
1023 gfc_expr
*op1
, *op2
;
1026 gfc_constructor
*c
, *new_c
;
1027 gfc_constructor_base oldbase
, newbase
;
1030 /* Array constructors have rank one. */
1034 op1
= e
->value
.op
.op1
;
1035 op2
= e
->value
.op
.op2
;
1037 if (op1
->expr_type
== EXPR_ARRAY
&& op2
->rank
== 0)
1038 scalar_first
= false;
1039 else if (op2
->expr_type
== EXPR_ARRAY
&& op1
->rank
== 0)
1041 scalar_first
= true;
1042 op1
= e
->value
.op
.op2
;
1043 op2
= e
->value
.op
.op1
;
1048 if (op2
->ts
.type
== BT_CHARACTER
)
1051 if (op2
->expr_type
== EXPR_CONSTANT
)
1052 scalar
= gfc_copy_expr (op2
);
1054 scalar
= create_var (gfc_copy_expr (op2
));
1056 oldbase
= op1
->value
.constructor
;
1058 e
->expr_type
= EXPR_ARRAY
;
1060 for (c
= gfc_constructor_first (oldbase
); c
;
1061 c
= gfc_constructor_next (c
))
1063 new_expr
= gfc_get_expr ();
1064 new_expr
->ts
= e
->ts
;
1065 new_expr
->expr_type
= EXPR_OP
;
1066 new_expr
->rank
= c
->expr
->rank
;
1067 new_expr
->where
= c
->where
;
1068 new_expr
->value
.op
.op
= e
->value
.op
.op
;
1072 new_expr
->value
.op
.op1
= gfc_copy_expr (scalar
);
1073 new_expr
->value
.op
.op2
= gfc_copy_expr (c
->expr
);
1077 new_expr
->value
.op
.op1
= gfc_copy_expr (c
->expr
);
1078 new_expr
->value
.op
.op2
= gfc_copy_expr (scalar
);
1081 new_c
= gfc_constructor_append_expr (&newbase
, new_expr
, &(e
->where
));
1082 new_c
->iterator
= c
->iterator
;
1086 gfc_free_expr (op1
);
1087 gfc_free_expr (op2
);
1088 gfc_free_expr (scalar
);
1090 e
->value
.constructor
= newbase
;
1094 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1095 2**k into ishift(1,k) */
1098 optimize_power (gfc_expr
*e
)
1100 gfc_expr
*op1
, *op2
;
1101 gfc_expr
*iand
, *ishft
;
1103 if (e
->ts
.type
!= BT_INTEGER
)
1106 op1
= e
->value
.op
.op1
;
1108 if (op1
== NULL
|| op1
->expr_type
!= EXPR_CONSTANT
)
1111 if (mpz_cmp_si (op1
->value
.integer
, -1L) == 0)
1113 gfc_free_expr (op1
);
1115 op2
= e
->value
.op
.op2
;
1120 iand
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_IAND
,
1121 "_internal_iand", e
->where
, 2, op2
,
1122 gfc_get_int_expr (e
->ts
.kind
,
1125 ishft
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ISHFT
,
1126 "_internal_ishft", e
->where
, 2, iand
,
1127 gfc_get_int_expr (e
->ts
.kind
,
1130 e
->value
.op
.op
= INTRINSIC_MINUS
;
1131 e
->value
.op
.op1
= gfc_get_int_expr (e
->ts
.kind
, &e
->where
, 1);
1132 e
->value
.op
.op2
= ishft
;
1135 else if (mpz_cmp_si (op1
->value
.integer
, 2L) == 0)
1137 gfc_free_expr (op1
);
1139 op2
= e
->value
.op
.op2
;
1143 ishft
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ISHFT
,
1144 "_internal_ishft", e
->where
, 2,
1145 gfc_get_int_expr (e
->ts
.kind
,
1152 else if (mpz_cmp_si (op1
->value
.integer
, 1L) == 0)
1154 op2
= e
->value
.op
.op2
;
1158 gfc_free_expr (op1
);
1159 gfc_free_expr (op2
);
1161 e
->expr_type
= EXPR_CONSTANT
;
1162 e
->value
.op
.op1
= NULL
;
1163 e
->value
.op
.op2
= NULL
;
1164 mpz_init_set_si (e
->value
.integer
, 1);
1165 /* Typespec and location are still OK. */
1172 /* Recursive optimization of operators. */
1175 optimize_op (gfc_expr
*e
)
1179 gfc_intrinsic_op op
= e
->value
.op
.op
;
1183 /* Only use new-style comparisons. */
1186 case INTRINSIC_EQ_OS
:
1190 case INTRINSIC_GE_OS
:
1194 case INTRINSIC_LE_OS
:
1198 case INTRINSIC_NE_OS
:
1202 case INTRINSIC_GT_OS
:
1206 case INTRINSIC_LT_OS
:
1222 changed
= optimize_comparison (e
, op
);
1225 /* Look at array constructors. */
1226 case INTRINSIC_PLUS
:
1227 case INTRINSIC_MINUS
:
1228 case INTRINSIC_TIMES
:
1229 case INTRINSIC_DIVIDE
:
1230 return combine_array_constructor (e
) || changed
;
1232 case INTRINSIC_POWER
:
1233 return optimize_power (e
);
1244 /* Return true if a constant string contains only blanks. */
1247 is_empty_string (gfc_expr
*e
)
1251 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_CONSTANT
)
1254 for (i
=0; i
< e
->value
.character
.length
; i
++)
1256 if (e
->value
.character
.string
[i
] != ' ')
1264 /* Insert a call to the intrinsic len_trim. Use a different name for
1265 the symbol tree so we don't run into trouble when the user has
1266 renamed len_trim for some reason. */
1269 get_len_trim_call (gfc_expr
*str
, int kind
)
1272 gfc_actual_arglist
*actual_arglist
, *next
;
1274 fcn
= gfc_get_expr ();
1275 fcn
->expr_type
= EXPR_FUNCTION
;
1276 fcn
->value
.function
.isym
= gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM
);
1277 actual_arglist
= gfc_get_actual_arglist ();
1278 actual_arglist
->expr
= str
;
1279 next
= gfc_get_actual_arglist ();
1280 next
->expr
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, kind
);
1281 actual_arglist
->next
= next
;
1283 fcn
->value
.function
.actual
= actual_arglist
;
1284 fcn
->where
= str
->where
;
1285 fcn
->ts
.type
= BT_INTEGER
;
1286 fcn
->ts
.kind
= gfc_charlen_int_kind
;
1288 gfc_get_sym_tree ("__internal_len_trim", current_ns
, &fcn
->symtree
, false);
1289 fcn
->symtree
->n
.sym
->ts
= fcn
->ts
;
1290 fcn
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
1291 fcn
->symtree
->n
.sym
->attr
.function
= 1;
1292 fcn
->symtree
->n
.sym
->attr
.elemental
= 1;
1293 fcn
->symtree
->n
.sym
->attr
.referenced
= 1;
1294 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
1295 gfc_commit_symbol (fcn
->symtree
->n
.sym
);
1300 /* Optimize expressions for equality. */
1303 optimize_comparison (gfc_expr
*e
, gfc_intrinsic_op op
)
1305 gfc_expr
*op1
, *op2
;
1309 gfc_actual_arglist
*firstarg
, *secondarg
;
1311 if (e
->expr_type
== EXPR_OP
)
1315 op1
= e
->value
.op
.op1
;
1316 op2
= e
->value
.op
.op2
;
1318 else if (e
->expr_type
== EXPR_FUNCTION
)
1320 /* One of the lexical comparison functions. */
1321 firstarg
= e
->value
.function
.actual
;
1322 secondarg
= firstarg
->next
;
1323 op1
= firstarg
->expr
;
1324 op2
= secondarg
->expr
;
1329 /* Strip off unneeded TRIM calls from string comparisons. */
1331 change
= remove_trim (op1
);
1333 if (remove_trim (op2
))
1336 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1337 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
1338 handles them well). However, there are also cases that need a non-scalar
1339 argument. For example the any intrinsic. See PR 45380. */
1343 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
1345 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
1346 && (op
== INTRINSIC_EQ
|| op
== INTRINSIC_NE
))
1348 bool empty_op1
, empty_op2
;
1349 empty_op1
= is_empty_string (op1
);
1350 empty_op2
= is_empty_string (op2
);
1352 if (empty_op1
|| empty_op2
)
1358 /* This can only happen when an error for comparing
1359 characters of different kinds has already been issued. */
1360 if (empty_op1
&& empty_op2
)
1363 zero
= gfc_get_int_expr (gfc_charlen_int_kind
, &e
->where
, 0);
1364 str
= empty_op1
? op2
: op1
;
1366 fcn
= get_len_trim_call (str
, gfc_charlen_int_kind
);
1370 gfc_free_expr (op1
);
1372 gfc_free_expr (op2
);
1376 e
->value
.op
.op1
= fcn
;
1377 e
->value
.op
.op2
= zero
;
1382 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
1384 if (flag_finite_math_only
1385 || (op1
->ts
.type
!= BT_REAL
&& op2
->ts
.type
!= BT_REAL
1386 && op1
->ts
.type
!= BT_COMPLEX
&& op2
->ts
.type
!= BT_COMPLEX
))
1388 eq
= gfc_dep_compare_expr (op1
, op2
);
1391 /* Replace A // B < A // C with B < C, and A // B < C // B
1393 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
1394 && op1
->value
.op
.op
== INTRINSIC_CONCAT
1395 && op2
->value
.op
.op
== INTRINSIC_CONCAT
)
1397 gfc_expr
*op1_left
= op1
->value
.op
.op1
;
1398 gfc_expr
*op2_left
= op2
->value
.op
.op1
;
1399 gfc_expr
*op1_right
= op1
->value
.op
.op2
;
1400 gfc_expr
*op2_right
= op2
->value
.op
.op2
;
1402 if (gfc_dep_compare_expr (op1_left
, op2_left
) == 0)
1404 /* Watch out for 'A ' // x vs. 'A' // x. */
1406 if (op1_left
->expr_type
== EXPR_CONSTANT
1407 && op2_left
->expr_type
== EXPR_CONSTANT
1408 && op1_left
->value
.character
.length
1409 != op2_left
->value
.character
.length
)
1417 firstarg
->expr
= op1_right
;
1418 secondarg
->expr
= op2_right
;
1422 e
->value
.op
.op1
= op1_right
;
1423 e
->value
.op
.op2
= op2_right
;
1425 optimize_comparison (e
, op
);
1429 if (gfc_dep_compare_expr (op1_right
, op2_right
) == 0)
1435 firstarg
->expr
= op1_left
;
1436 secondarg
->expr
= op2_left
;
1440 e
->value
.op
.op1
= op1_left
;
1441 e
->value
.op
.op2
= op2_left
;
1444 optimize_comparison (e
, op
);
1451 /* eq can only be -1, 0 or 1 at this point. */
1479 gfc_internal_error ("illegal OP in optimize_comparison");
1483 /* Replace the expression by a constant expression. The typespec
1484 and where remains the way it is. */
1487 e
->expr_type
= EXPR_CONSTANT
;
1488 e
->value
.logical
= result
;
1496 /* Optimize a trim function by replacing it with an equivalent substring
1497 involving a call to len_trim. This only works for expressions where
1498 variables are trimmed. Return true if anything was modified. */
1501 optimize_trim (gfc_expr
*e
)
1506 gfc_ref
**rr
= NULL
;
1508 /* Don't do this optimization within an argument list, because
1509 otherwise aliasing issues may occur. */
1511 if (count_arglist
!= 1)
1514 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_FUNCTION
1515 || e
->value
.function
.isym
== NULL
1516 || e
->value
.function
.isym
->id
!= GFC_ISYM_TRIM
)
1519 a
= e
->value
.function
.actual
->expr
;
1521 if (a
->expr_type
!= EXPR_VARIABLE
)
1524 /* Follow all references to find the correct place to put the newly
1525 created reference. FIXME: Also handle substring references and
1526 array references. Array references cause strange regressions at
1531 for (rr
= &(a
->ref
); *rr
; rr
= &((*rr
)->next
))
1533 if ((*rr
)->type
== REF_SUBSTRING
|| (*rr
)->type
== REF_ARRAY
)
1538 strip_function_call (e
);
1543 /* Create the reference. */
1545 ref
= gfc_get_ref ();
1546 ref
->type
= REF_SUBSTRING
;
1548 /* Set the start of the reference. */
1550 ref
->u
.ss
.start
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 1);
1552 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
1554 fcn
= get_len_trim_call (gfc_copy_expr (e
), gfc_default_integer_kind
);
1556 /* Set the end of the reference to the call to len_trim. */
1558 ref
->u
.ss
.end
= fcn
;
1559 gcc_assert (rr
!= NULL
&& *rr
== NULL
);
1564 /* Optimize minloc(b), where b is rank 1 array, into
1565 (/ minloc(b, dim=1) /), and similarly for maxloc,
1566 as the latter forms are expanded inline. */
1569 optimize_minmaxloc (gfc_expr
**e
)
1572 gfc_actual_arglist
*a
;
1576 || fn
->value
.function
.actual
== NULL
1577 || fn
->value
.function
.actual
->expr
== NULL
1578 || fn
->value
.function
.actual
->expr
->rank
!= 1)
1581 *e
= gfc_get_array_expr (fn
->ts
.type
, fn
->ts
.kind
, &fn
->where
);
1582 (*e
)->shape
= fn
->shape
;
1585 gfc_constructor_append_expr (&(*e
)->value
.constructor
, fn
, &fn
->where
);
1587 name
= XALLOCAVEC (char, strlen (fn
->value
.function
.name
) + 1);
1588 strcpy (name
, fn
->value
.function
.name
);
1589 p
= strstr (name
, "loc0");
1591 fn
->value
.function
.name
= gfc_get_string (name
);
1592 if (fn
->value
.function
.actual
->next
)
1594 a
= fn
->value
.function
.actual
->next
;
1595 gcc_assert (a
->expr
== NULL
);
1599 a
= gfc_get_actual_arglist ();
1600 fn
->value
.function
.actual
->next
= a
;
1602 a
->expr
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
1604 mpz_set_ui (a
->expr
->value
.integer
, 1);
1607 /* Callback function for code checking that we do not pass a DO variable to an
1608 INTENT(OUT) or INTENT(INOUT) dummy variable. */
1611 doloop_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1612 void *data ATTRIBUTE_UNUSED
)
1616 gfc_formal_arglist
*f
;
1617 gfc_actual_arglist
*a
;
1625 /* Grow the temporary storage if necessary. */
1626 if (doloop_level
>= doloop_size
)
1628 doloop_size
= 2 * doloop_size
;
1629 doloop_list
= XRESIZEVEC (gfc_code
*, doloop_list
, doloop_size
);
1632 /* Mark the DO loop variable if there is one. */
1633 if (co
->ext
.iterator
&& co
->ext
.iterator
->var
)
1634 doloop_list
[doloop_level
] = co
;
1636 doloop_list
[doloop_level
] = NULL
;
1641 if (co
->resolved_sym
== NULL
)
1644 f
= gfc_sym_get_dummy_args (co
->resolved_sym
);
1646 /* Withot a formal arglist, there is only unknown INTENT,
1647 which we don't check for. */
1655 for (i
=0; i
<doloop_level
; i
++)
1659 if (doloop_list
[i
] == NULL
)
1662 do_sym
= doloop_list
[i
]->ext
.iterator
->var
->symtree
->n
.sym
;
1664 if (a
->expr
&& a
->expr
->symtree
1665 && a
->expr
->symtree
->n
.sym
== do_sym
)
1667 if (f
->sym
->attr
.intent
== INTENT_OUT
)
1668 gfc_error_now("Variable '%s' at %L set to undefined value "
1669 "inside loop beginning at %L as INTENT(OUT) "
1670 "argument to subroutine '%s'", do_sym
->name
,
1671 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1672 co
->symtree
->n
.sym
->name
);
1673 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
1674 gfc_error_now("Variable '%s' at %L not definable inside loop "
1675 "beginning at %L as INTENT(INOUT) argument to "
1676 "subroutine '%s'", do_sym
->name
,
1677 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1678 co
->symtree
->n
.sym
->name
);
1692 /* Callback function for functions checking that we do not pass a DO variable
1693 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
1696 do_function (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1697 void *data ATTRIBUTE_UNUSED
)
1699 gfc_formal_arglist
*f
;
1700 gfc_actual_arglist
*a
;
1705 if (expr
->expr_type
!= EXPR_FUNCTION
)
1708 /* Intrinsic functions don't modify their arguments. */
1710 if (expr
->value
.function
.isym
)
1713 f
= gfc_sym_get_dummy_args (expr
->symtree
->n
.sym
);
1715 /* Without a formal arglist, there is only unknown INTENT,
1716 which we don't check for. */
1720 a
= expr
->value
.function
.actual
;
1724 for (i
=0; i
<doloop_level
; i
++)
1729 if (doloop_list
[i
] == NULL
)
1732 do_sym
= doloop_list
[i
]->ext
.iterator
->var
->symtree
->n
.sym
;
1734 if (a
->expr
&& a
->expr
->symtree
1735 && a
->expr
->symtree
->n
.sym
== do_sym
)
1737 if (f
->sym
->attr
.intent
== INTENT_OUT
)
1738 gfc_error_now("Variable '%s' at %L set to undefined value "
1739 "inside loop beginning at %L as INTENT(OUT) "
1740 "argument to function '%s'", do_sym
->name
,
1741 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1742 expr
->symtree
->n
.sym
->name
);
1743 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
1744 gfc_error_now("Variable '%s' at %L not definable inside loop "
1745 "beginning at %L as INTENT(INOUT) argument to "
1746 "function '%s'", do_sym
->name
,
1747 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1748 expr
->symtree
->n
.sym
->name
);
1759 doloop_warn (gfc_namespace
*ns
)
1761 gfc_code_walker (&ns
->code
, doloop_code
, do_function
, NULL
);
1765 #define WALK_SUBEXPR(NODE) \
1768 result = gfc_expr_walker (&(NODE), exprfn, data); \
1773 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
1775 /* Walk expression *E, calling EXPRFN on each expression in it. */
1778 gfc_expr_walker (gfc_expr
**e
, walk_expr_fn_t exprfn
, void *data
)
1782 int walk_subtrees
= 1;
1783 gfc_actual_arglist
*a
;
1787 int result
= exprfn (e
, &walk_subtrees
, data
);
1791 switch ((*e
)->expr_type
)
1794 WALK_SUBEXPR ((*e
)->value
.op
.op1
);
1795 WALK_SUBEXPR_TAIL ((*e
)->value
.op
.op2
);
1798 for (a
= (*e
)->value
.function
.actual
; a
; a
= a
->next
)
1799 WALK_SUBEXPR (a
->expr
);
1803 WALK_SUBEXPR ((*e
)->value
.compcall
.base_object
);
1804 for (a
= (*e
)->value
.compcall
.actual
; a
; a
= a
->next
)
1805 WALK_SUBEXPR (a
->expr
);
1808 case EXPR_STRUCTURE
:
1810 for (c
= gfc_constructor_first ((*e
)->value
.constructor
); c
;
1811 c
= gfc_constructor_next (c
))
1813 if (c
->iterator
== NULL
)
1814 WALK_SUBEXPR (c
->expr
);
1818 WALK_SUBEXPR (c
->expr
);
1820 WALK_SUBEXPR (c
->iterator
->var
);
1821 WALK_SUBEXPR (c
->iterator
->start
);
1822 WALK_SUBEXPR (c
->iterator
->end
);
1823 WALK_SUBEXPR (c
->iterator
->step
);
1827 if ((*e
)->expr_type
!= EXPR_ARRAY
)
1830 /* Fall through to the variable case in order to walk the
1833 case EXPR_SUBSTRING
:
1835 for (r
= (*e
)->ref
; r
; r
= r
->next
)
1844 if (ar
->type
== AR_SECTION
|| ar
->type
== AR_ELEMENT
)
1846 for (i
=0; i
< ar
->dimen
; i
++)
1848 WALK_SUBEXPR (ar
->start
[i
]);
1849 WALK_SUBEXPR (ar
->end
[i
]);
1850 WALK_SUBEXPR (ar
->stride
[i
]);
1857 WALK_SUBEXPR (r
->u
.ss
.start
);
1858 WALK_SUBEXPR (r
->u
.ss
.end
);
1874 #define WALK_SUBCODE(NODE) \
1877 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
1883 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
1884 on each expression in it. If any of the hooks returns non-zero, that
1885 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
1886 no subcodes or subexpressions are traversed. */
1889 gfc_code_walker (gfc_code
**c
, walk_code_fn_t codefn
, walk_expr_fn_t exprfn
,
1892 for (; *c
; c
= &(*c
)->next
)
1894 int walk_subtrees
= 1;
1895 int result
= codefn (c
, &walk_subtrees
, data
);
1902 gfc_actual_arglist
*a
;
1904 gfc_association_list
*alist
;
1905 bool saved_in_omp_workshare
;
1907 /* There might be statement insertions before the current code,
1908 which must not affect the expression walker. */
1911 saved_in_omp_workshare
= in_omp_workshare
;
1917 WALK_SUBCODE (co
->ext
.block
.ns
->code
);
1918 for (alist
= co
->ext
.block
.assoc
; alist
; alist
= alist
->next
)
1919 WALK_SUBEXPR (alist
->target
);
1924 WALK_SUBEXPR (co
->ext
.iterator
->var
);
1925 WALK_SUBEXPR (co
->ext
.iterator
->start
);
1926 WALK_SUBEXPR (co
->ext
.iterator
->end
);
1927 WALK_SUBEXPR (co
->ext
.iterator
->step
);
1931 case EXEC_ASSIGN_CALL
:
1932 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
1933 WALK_SUBEXPR (a
->expr
);
1937 WALK_SUBEXPR (co
->expr1
);
1938 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
1939 WALK_SUBEXPR (a
->expr
);
1943 WALK_SUBEXPR (co
->expr1
);
1944 for (b
= co
->block
; b
; b
= b
->block
)
1947 for (cp
= b
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
1949 WALK_SUBEXPR (cp
->low
);
1950 WALK_SUBEXPR (cp
->high
);
1952 WALK_SUBCODE (b
->next
);
1957 case EXEC_DEALLOCATE
:
1960 for (a
= co
->ext
.alloc
.list
; a
; a
= a
->next
)
1961 WALK_SUBEXPR (a
->expr
);
1966 case EXEC_DO_CONCURRENT
:
1968 gfc_forall_iterator
*fa
;
1969 for (fa
= co
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
1971 WALK_SUBEXPR (fa
->var
);
1972 WALK_SUBEXPR (fa
->start
);
1973 WALK_SUBEXPR (fa
->end
);
1974 WALK_SUBEXPR (fa
->stride
);
1976 if (co
->op
== EXEC_FORALL
)
1982 WALK_SUBEXPR (co
->ext
.open
->unit
);
1983 WALK_SUBEXPR (co
->ext
.open
->file
);
1984 WALK_SUBEXPR (co
->ext
.open
->status
);
1985 WALK_SUBEXPR (co
->ext
.open
->access
);
1986 WALK_SUBEXPR (co
->ext
.open
->form
);
1987 WALK_SUBEXPR (co
->ext
.open
->recl
);
1988 WALK_SUBEXPR (co
->ext
.open
->blank
);
1989 WALK_SUBEXPR (co
->ext
.open
->position
);
1990 WALK_SUBEXPR (co
->ext
.open
->action
);
1991 WALK_SUBEXPR (co
->ext
.open
->delim
);
1992 WALK_SUBEXPR (co
->ext
.open
->pad
);
1993 WALK_SUBEXPR (co
->ext
.open
->iostat
);
1994 WALK_SUBEXPR (co
->ext
.open
->iomsg
);
1995 WALK_SUBEXPR (co
->ext
.open
->convert
);
1996 WALK_SUBEXPR (co
->ext
.open
->decimal
);
1997 WALK_SUBEXPR (co
->ext
.open
->encoding
);
1998 WALK_SUBEXPR (co
->ext
.open
->round
);
1999 WALK_SUBEXPR (co
->ext
.open
->sign
);
2000 WALK_SUBEXPR (co
->ext
.open
->asynchronous
);
2001 WALK_SUBEXPR (co
->ext
.open
->id
);
2002 WALK_SUBEXPR (co
->ext
.open
->newunit
);
2006 WALK_SUBEXPR (co
->ext
.close
->unit
);
2007 WALK_SUBEXPR (co
->ext
.close
->status
);
2008 WALK_SUBEXPR (co
->ext
.close
->iostat
);
2009 WALK_SUBEXPR (co
->ext
.close
->iomsg
);
2012 case EXEC_BACKSPACE
:
2016 WALK_SUBEXPR (co
->ext
.filepos
->unit
);
2017 WALK_SUBEXPR (co
->ext
.filepos
->iostat
);
2018 WALK_SUBEXPR (co
->ext
.filepos
->iomsg
);
2022 WALK_SUBEXPR (co
->ext
.inquire
->unit
);
2023 WALK_SUBEXPR (co
->ext
.inquire
->file
);
2024 WALK_SUBEXPR (co
->ext
.inquire
->iomsg
);
2025 WALK_SUBEXPR (co
->ext
.inquire
->iostat
);
2026 WALK_SUBEXPR (co
->ext
.inquire
->exist
);
2027 WALK_SUBEXPR (co
->ext
.inquire
->opened
);
2028 WALK_SUBEXPR (co
->ext
.inquire
->number
);
2029 WALK_SUBEXPR (co
->ext
.inquire
->named
);
2030 WALK_SUBEXPR (co
->ext
.inquire
->name
);
2031 WALK_SUBEXPR (co
->ext
.inquire
->access
);
2032 WALK_SUBEXPR (co
->ext
.inquire
->sequential
);
2033 WALK_SUBEXPR (co
->ext
.inquire
->direct
);
2034 WALK_SUBEXPR (co
->ext
.inquire
->form
);
2035 WALK_SUBEXPR (co
->ext
.inquire
->formatted
);
2036 WALK_SUBEXPR (co
->ext
.inquire
->unformatted
);
2037 WALK_SUBEXPR (co
->ext
.inquire
->recl
);
2038 WALK_SUBEXPR (co
->ext
.inquire
->nextrec
);
2039 WALK_SUBEXPR (co
->ext
.inquire
->blank
);
2040 WALK_SUBEXPR (co
->ext
.inquire
->position
);
2041 WALK_SUBEXPR (co
->ext
.inquire
->action
);
2042 WALK_SUBEXPR (co
->ext
.inquire
->read
);
2043 WALK_SUBEXPR (co
->ext
.inquire
->write
);
2044 WALK_SUBEXPR (co
->ext
.inquire
->readwrite
);
2045 WALK_SUBEXPR (co
->ext
.inquire
->delim
);
2046 WALK_SUBEXPR (co
->ext
.inquire
->encoding
);
2047 WALK_SUBEXPR (co
->ext
.inquire
->pad
);
2048 WALK_SUBEXPR (co
->ext
.inquire
->iolength
);
2049 WALK_SUBEXPR (co
->ext
.inquire
->convert
);
2050 WALK_SUBEXPR (co
->ext
.inquire
->strm_pos
);
2051 WALK_SUBEXPR (co
->ext
.inquire
->asynchronous
);
2052 WALK_SUBEXPR (co
->ext
.inquire
->decimal
);
2053 WALK_SUBEXPR (co
->ext
.inquire
->pending
);
2054 WALK_SUBEXPR (co
->ext
.inquire
->id
);
2055 WALK_SUBEXPR (co
->ext
.inquire
->sign
);
2056 WALK_SUBEXPR (co
->ext
.inquire
->size
);
2057 WALK_SUBEXPR (co
->ext
.inquire
->round
);
2061 WALK_SUBEXPR (co
->ext
.wait
->unit
);
2062 WALK_SUBEXPR (co
->ext
.wait
->iostat
);
2063 WALK_SUBEXPR (co
->ext
.wait
->iomsg
);
2064 WALK_SUBEXPR (co
->ext
.wait
->id
);
2069 WALK_SUBEXPR (co
->ext
.dt
->io_unit
);
2070 WALK_SUBEXPR (co
->ext
.dt
->format_expr
);
2071 WALK_SUBEXPR (co
->ext
.dt
->rec
);
2072 WALK_SUBEXPR (co
->ext
.dt
->advance
);
2073 WALK_SUBEXPR (co
->ext
.dt
->iostat
);
2074 WALK_SUBEXPR (co
->ext
.dt
->size
);
2075 WALK_SUBEXPR (co
->ext
.dt
->iomsg
);
2076 WALK_SUBEXPR (co
->ext
.dt
->id
);
2077 WALK_SUBEXPR (co
->ext
.dt
->pos
);
2078 WALK_SUBEXPR (co
->ext
.dt
->asynchronous
);
2079 WALK_SUBEXPR (co
->ext
.dt
->blank
);
2080 WALK_SUBEXPR (co
->ext
.dt
->decimal
);
2081 WALK_SUBEXPR (co
->ext
.dt
->delim
);
2082 WALK_SUBEXPR (co
->ext
.dt
->pad
);
2083 WALK_SUBEXPR (co
->ext
.dt
->round
);
2084 WALK_SUBEXPR (co
->ext
.dt
->sign
);
2085 WALK_SUBEXPR (co
->ext
.dt
->extra_comma
);
2088 case EXEC_OMP_PARALLEL
:
2089 case EXEC_OMP_PARALLEL_DO
:
2090 case EXEC_OMP_PARALLEL_SECTIONS
:
2092 in_omp_workshare
= false;
2094 /* This goto serves as a shortcut to avoid code
2095 duplication or a larger if or switch statement. */
2096 goto check_omp_clauses
;
2098 case EXEC_OMP_WORKSHARE
:
2099 case EXEC_OMP_PARALLEL_WORKSHARE
:
2101 in_omp_workshare
= true;
2106 case EXEC_OMP_SECTIONS
:
2107 case EXEC_OMP_SINGLE
:
2108 case EXEC_OMP_END_SINGLE
:
2111 /* Come to this label only from the
2112 EXEC_OMP_PARALLEL_* cases above. */
2116 if (co
->ext
.omp_clauses
)
2118 WALK_SUBEXPR (co
->ext
.omp_clauses
->if_expr
);
2119 WALK_SUBEXPR (co
->ext
.omp_clauses
->final_expr
);
2120 WALK_SUBEXPR (co
->ext
.omp_clauses
->num_threads
);
2121 WALK_SUBEXPR (co
->ext
.omp_clauses
->chunk_size
);
2128 WALK_SUBEXPR (co
->expr1
);
2129 WALK_SUBEXPR (co
->expr2
);
2130 WALK_SUBEXPR (co
->expr3
);
2131 WALK_SUBEXPR (co
->expr4
);
2132 for (b
= co
->block
; b
; b
= b
->block
)
2134 WALK_SUBEXPR (b
->expr1
);
2135 WALK_SUBEXPR (b
->expr2
);
2136 WALK_SUBCODE (b
->next
);
2139 if (co
->op
== EXEC_FORALL
)
2142 if (co
->op
== EXEC_DO
)
2145 in_omp_workshare
= saved_in_omp_workshare
;