1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2014 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
, void *data ATTRIBUTE_UNUSED
)
633 inserted_block
= NULL
;
634 changed_statement
= NULL
;
636 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
637 and allocation on assigment are prohibited inside WHERE, and finally
638 masking an expression would lead to wrong-code when replacing
641 b = sum(foo(a) + foo(a))
652 if ((*c
)->op
== EXEC_WHERE
)
662 /* Dummy function for expression call back, for use when we
663 really don't want to do any walking. */
666 dummy_expr_callback (gfc_expr
**e ATTRIBUTE_UNUSED
, int *walk_subtrees
,
667 void *data ATTRIBUTE_UNUSED
)
673 /* Dummy function for code callback, for use when we really
674 don't want to do anything. */
676 dummy_code_callback (gfc_code
**e ATTRIBUTE_UNUSED
,
677 int *walk_subtrees ATTRIBUTE_UNUSED
,
678 void *data ATTRIBUTE_UNUSED
)
683 /* Code callback function for converting
690 This is because common function elimination would otherwise place the
691 temporary variables outside the loop. */
694 convert_do_while (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
695 void *data ATTRIBUTE_UNUSED
)
698 gfc_code
*c_if1
, *c_if2
, *c_exit
;
700 gfc_expr
*e_not
, *e_cond
;
702 if (co
->op
!= EXEC_DO_WHILE
)
705 if (co
->expr1
== NULL
|| co
->expr1
->expr_type
== EXPR_CONSTANT
)
710 /* Generate the condition of the if statement, which is .not. the original
712 e_not
= gfc_get_expr ();
713 e_not
->ts
= e_cond
->ts
;
714 e_not
->where
= e_cond
->where
;
715 e_not
->expr_type
= EXPR_OP
;
716 e_not
->value
.op
.op
= INTRINSIC_NOT
;
717 e_not
->value
.op
.op1
= e_cond
;
719 /* Generate the EXIT statement. */
720 c_exit
= XCNEW (gfc_code
);
721 c_exit
->op
= EXEC_EXIT
;
722 c_exit
->ext
.which_construct
= co
;
723 c_exit
->loc
= co
->loc
;
725 /* Generate the IF statement. */
726 c_if2
= XCNEW (gfc_code
);
728 c_if2
->expr1
= e_not
;
729 c_if2
->next
= c_exit
;
730 c_if2
->loc
= co
->loc
;
732 /* ... plus the one to chain it to. */
733 c_if1
= XCNEW (gfc_code
);
735 c_if1
->block
= c_if2
;
736 c_if1
->loc
= co
->loc
;
738 /* Make the DO WHILE loop into a DO block by replacing the condition
739 with a true constant. */
740 co
->expr1
= gfc_get_logical_expr (gfc_default_integer_kind
, &co
->loc
, true);
742 /* Hang the generated if statement into the loop body. */
744 loopblock
= co
->block
->next
;
745 co
->block
->next
= c_if1
;
746 c_if1
->next
= loopblock
;
751 /* Code callback function for converting
764 because otherwise common function elimination would place the BLOCKs
765 into the wrong place. */
768 convert_elseif (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
769 void *data ATTRIBUTE_UNUSED
)
772 gfc_code
*c_if1
, *c_if2
, *else_stmt
;
774 if (co
->op
!= EXEC_IF
)
777 /* This loop starts out with the first ELSE statement. */
778 else_stmt
= co
->block
->block
;
780 while (else_stmt
!= NULL
)
784 /* If there is no condition, we're done. */
785 if (else_stmt
->expr1
== NULL
)
788 next_else
= else_stmt
->block
;
790 /* Generate the new IF statement. */
791 c_if2
= XCNEW (gfc_code
);
793 c_if2
->expr1
= else_stmt
->expr1
;
794 c_if2
->next
= else_stmt
->next
;
795 c_if2
->loc
= else_stmt
->loc
;
796 c_if2
->block
= next_else
;
798 /* ... plus the one to chain it to. */
799 c_if1
= XCNEW (gfc_code
);
801 c_if1
->block
= c_if2
;
802 c_if1
->loc
= else_stmt
->loc
;
804 /* Insert the new IF after the ELSE. */
805 else_stmt
->expr1
= NULL
;
806 else_stmt
->next
= c_if1
;
807 else_stmt
->block
= NULL
;
809 else_stmt
= next_else
;
811 /* Don't walk subtrees. */
814 /* Optimize a namespace, including all contained namespaces. */
817 optimize_namespace (gfc_namespace
*ns
)
823 in_omp_workshare
= false;
825 gfc_code_walker (&ns
->code
, convert_do_while
, dummy_expr_callback
, NULL
);
826 gfc_code_walker (&ns
->code
, convert_elseif
, dummy_expr_callback
, NULL
);
827 gfc_code_walker (&ns
->code
, cfe_code
, cfe_expr_0
, NULL
);
828 gfc_code_walker (&ns
->code
, optimize_code
, optimize_expr
, NULL
);
830 /* BLOCKs are handled in the expression walker below. */
831 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
833 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
834 optimize_namespace (ns
);
839 optimize_reduction (gfc_namespace
*ns
)
842 gfc_code_walker (&ns
->code
, dummy_code_callback
, callback_reduction
, NULL
);
844 /* BLOCKs are handled in the expression walker below. */
845 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
847 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
848 optimize_reduction (ns
);
855 a = matmul(b,c) ; a = a + d
856 where the array function is not elemental and not allocatable
857 and does not depend on the left-hand side.
861 optimize_binop_array_assignment (gfc_code
*c
, gfc_expr
**rhs
, bool seen_op
)
866 if (e
->expr_type
== EXPR_OP
)
868 switch (e
->value
.op
.op
)
870 /* Unary operators and exponentiation: Only look at a single
873 case INTRINSIC_UPLUS
:
874 case INTRINSIC_UMINUS
:
875 case INTRINSIC_PARENTHESES
:
876 case INTRINSIC_POWER
:
877 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, seen_op
))
882 /* Binary operators. */
883 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, true))
886 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op2
, true))
892 else if (seen_op
&& e
->expr_type
== EXPR_FUNCTION
&& e
->rank
> 0
893 && ! (e
->value
.function
.esym
894 && (e
->value
.function
.esym
->attr
.elemental
895 || e
->value
.function
.esym
->attr
.allocatable
896 || e
->value
.function
.esym
->ts
.type
!= c
->expr1
->ts
.type
897 || e
->value
.function
.esym
->ts
.kind
!= c
->expr1
->ts
.kind
))
898 && ! (e
->value
.function
.isym
899 && (e
->value
.function
.isym
->elemental
900 || e
->ts
.type
!= c
->expr1
->ts
.type
901 || e
->ts
.kind
!= c
->expr1
->ts
.kind
))
902 && ! gfc_inline_intrinsic_function_p (e
))
908 /* Insert a new assignment statement after the current one. */
909 n
= XCNEW (gfc_code
);
915 n
->expr1
= gfc_copy_expr (c
->expr1
);
917 new_expr
= gfc_copy_expr (c
->expr1
);
925 /* Nothing to optimize. */
929 /* Remove unneeded TRIMs at the end of expressions. */
932 remove_trim (gfc_expr
*rhs
)
938 /* Check for a // b // trim(c). Looping is probably not
939 necessary because the parser usually generates
940 (// (// a b ) trim(c) ) , but better safe than sorry. */
942 while (rhs
->expr_type
== EXPR_OP
943 && rhs
->value
.op
.op
== INTRINSIC_CONCAT
)
944 rhs
= rhs
->value
.op
.op2
;
946 while (rhs
->expr_type
== EXPR_FUNCTION
&& rhs
->value
.function
.isym
947 && rhs
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
949 strip_function_call (rhs
);
950 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
958 /* Optimizations for an assignment. */
961 optimize_assignment (gfc_code
* c
)
968 if (lhs
->ts
.type
== BT_CHARACTER
&& !lhs
->ts
.deferred
)
970 /* Optimize a = trim(b) to a = b. */
973 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
974 if (is_empty_string (rhs
))
975 rhs
->value
.character
.length
= 0;
978 if (lhs
->rank
> 0 && gfc_check_dependency (lhs
, rhs
, true) == 0)
979 optimize_binop_array_assignment (c
, &rhs
, false);
983 /* Remove an unneeded function call, modifying the expression.
984 This replaces the function call with the value of its
985 first argument. The rest of the argument list is freed. */
988 strip_function_call (gfc_expr
*e
)
991 gfc_actual_arglist
*a
;
993 a
= e
->value
.function
.actual
;
995 /* We should have at least one argument. */
996 gcc_assert (a
->expr
!= NULL
);
1000 /* Free the remaining arglist, if any. */
1002 gfc_free_actual_arglist (a
->next
);
1004 /* Graft the argument expression onto the original function. */
1010 /* Optimization of lexical comparison functions. */
1013 optimize_lexical_comparison (gfc_expr
*e
)
1015 if (e
->expr_type
!= EXPR_FUNCTION
|| e
->value
.function
.isym
== NULL
)
1018 switch (e
->value
.function
.isym
->id
)
1021 return optimize_comparison (e
, INTRINSIC_LE
);
1024 return optimize_comparison (e
, INTRINSIC_GE
);
1027 return optimize_comparison (e
, INTRINSIC_GT
);
1030 return optimize_comparison (e
, INTRINSIC_LT
);
1038 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1039 do CHARACTER because of possible pessimization involving character
1043 combine_array_constructor (gfc_expr
*e
)
1046 gfc_expr
*op1
, *op2
;
1049 gfc_constructor
*c
, *new_c
;
1050 gfc_constructor_base oldbase
, newbase
;
1053 /* Array constructors have rank one. */
1057 op1
= e
->value
.op
.op1
;
1058 op2
= e
->value
.op
.op2
;
1060 if (op1
->expr_type
== EXPR_ARRAY
&& op2
->rank
== 0)
1061 scalar_first
= false;
1062 else if (op2
->expr_type
== EXPR_ARRAY
&& op1
->rank
== 0)
1064 scalar_first
= true;
1065 op1
= e
->value
.op
.op2
;
1066 op2
= e
->value
.op
.op1
;
1071 if (op2
->ts
.type
== BT_CHARACTER
)
1074 if (op2
->expr_type
== EXPR_CONSTANT
)
1075 scalar
= gfc_copy_expr (op2
);
1077 scalar
= create_var (gfc_copy_expr (op2
));
1079 oldbase
= op1
->value
.constructor
;
1081 e
->expr_type
= EXPR_ARRAY
;
1083 for (c
= gfc_constructor_first (oldbase
); c
;
1084 c
= gfc_constructor_next (c
))
1086 new_expr
= gfc_get_expr ();
1087 new_expr
->ts
= e
->ts
;
1088 new_expr
->expr_type
= EXPR_OP
;
1089 new_expr
->rank
= c
->expr
->rank
;
1090 new_expr
->where
= c
->where
;
1091 new_expr
->value
.op
.op
= e
->value
.op
.op
;
1095 new_expr
->value
.op
.op1
= gfc_copy_expr (scalar
);
1096 new_expr
->value
.op
.op2
= gfc_copy_expr (c
->expr
);
1100 new_expr
->value
.op
.op1
= gfc_copy_expr (c
->expr
);
1101 new_expr
->value
.op
.op2
= gfc_copy_expr (scalar
);
1104 new_c
= gfc_constructor_append_expr (&newbase
, new_expr
, &(e
->where
));
1105 new_c
->iterator
= c
->iterator
;
1109 gfc_free_expr (op1
);
1110 gfc_free_expr (op2
);
1111 gfc_free_expr (scalar
);
1113 e
->value
.constructor
= newbase
;
1117 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1118 2**k into ishift(1,k) */
1121 optimize_power (gfc_expr
*e
)
1123 gfc_expr
*op1
, *op2
;
1124 gfc_expr
*iand
, *ishft
;
1126 if (e
->ts
.type
!= BT_INTEGER
)
1129 op1
= e
->value
.op
.op1
;
1131 if (op1
== NULL
|| op1
->expr_type
!= EXPR_CONSTANT
)
1134 if (mpz_cmp_si (op1
->value
.integer
, -1L) == 0)
1136 gfc_free_expr (op1
);
1138 op2
= e
->value
.op
.op2
;
1143 iand
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_IAND
,
1144 "_internal_iand", e
->where
, 2, op2
,
1145 gfc_get_int_expr (e
->ts
.kind
,
1148 ishft
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ISHFT
,
1149 "_internal_ishft", e
->where
, 2, iand
,
1150 gfc_get_int_expr (e
->ts
.kind
,
1153 e
->value
.op
.op
= INTRINSIC_MINUS
;
1154 e
->value
.op
.op1
= gfc_get_int_expr (e
->ts
.kind
, &e
->where
, 1);
1155 e
->value
.op
.op2
= ishft
;
1158 else if (mpz_cmp_si (op1
->value
.integer
, 2L) == 0)
1160 gfc_free_expr (op1
);
1162 op2
= e
->value
.op
.op2
;
1166 ishft
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ISHFT
,
1167 "_internal_ishft", e
->where
, 2,
1168 gfc_get_int_expr (e
->ts
.kind
,
1175 else if (mpz_cmp_si (op1
->value
.integer
, 1L) == 0)
1177 op2
= e
->value
.op
.op2
;
1181 gfc_free_expr (op1
);
1182 gfc_free_expr (op2
);
1184 e
->expr_type
= EXPR_CONSTANT
;
1185 e
->value
.op
.op1
= NULL
;
1186 e
->value
.op
.op2
= NULL
;
1187 mpz_init_set_si (e
->value
.integer
, 1);
1188 /* Typespec and location are still OK. */
1195 /* Recursive optimization of operators. */
1198 optimize_op (gfc_expr
*e
)
1202 gfc_intrinsic_op op
= e
->value
.op
.op
;
1206 /* Only use new-style comparisons. */
1209 case INTRINSIC_EQ_OS
:
1213 case INTRINSIC_GE_OS
:
1217 case INTRINSIC_LE_OS
:
1221 case INTRINSIC_NE_OS
:
1225 case INTRINSIC_GT_OS
:
1229 case INTRINSIC_LT_OS
:
1245 changed
= optimize_comparison (e
, op
);
1248 /* Look at array constructors. */
1249 case INTRINSIC_PLUS
:
1250 case INTRINSIC_MINUS
:
1251 case INTRINSIC_TIMES
:
1252 case INTRINSIC_DIVIDE
:
1253 return combine_array_constructor (e
) || changed
;
1255 case INTRINSIC_POWER
:
1256 return optimize_power (e
);
1267 /* Return true if a constant string contains only blanks. */
1270 is_empty_string (gfc_expr
*e
)
1274 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_CONSTANT
)
1277 for (i
=0; i
< e
->value
.character
.length
; i
++)
1279 if (e
->value
.character
.string
[i
] != ' ')
1287 /* Insert a call to the intrinsic len_trim. Use a different name for
1288 the symbol tree so we don't run into trouble when the user has
1289 renamed len_trim for some reason. */
1292 get_len_trim_call (gfc_expr
*str
, int kind
)
1295 gfc_actual_arglist
*actual_arglist
, *next
;
1297 fcn
= gfc_get_expr ();
1298 fcn
->expr_type
= EXPR_FUNCTION
;
1299 fcn
->value
.function
.isym
= gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM
);
1300 actual_arglist
= gfc_get_actual_arglist ();
1301 actual_arglist
->expr
= str
;
1302 next
= gfc_get_actual_arglist ();
1303 next
->expr
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, kind
);
1304 actual_arglist
->next
= next
;
1306 fcn
->value
.function
.actual
= actual_arglist
;
1307 fcn
->where
= str
->where
;
1308 fcn
->ts
.type
= BT_INTEGER
;
1309 fcn
->ts
.kind
= gfc_charlen_int_kind
;
1311 gfc_get_sym_tree ("__internal_len_trim", current_ns
, &fcn
->symtree
, false);
1312 fcn
->symtree
->n
.sym
->ts
= fcn
->ts
;
1313 fcn
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
1314 fcn
->symtree
->n
.sym
->attr
.function
= 1;
1315 fcn
->symtree
->n
.sym
->attr
.elemental
= 1;
1316 fcn
->symtree
->n
.sym
->attr
.referenced
= 1;
1317 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
1318 gfc_commit_symbol (fcn
->symtree
->n
.sym
);
1323 /* Optimize expressions for equality. */
1326 optimize_comparison (gfc_expr
*e
, gfc_intrinsic_op op
)
1328 gfc_expr
*op1
, *op2
;
1332 gfc_actual_arglist
*firstarg
, *secondarg
;
1334 if (e
->expr_type
== EXPR_OP
)
1338 op1
= e
->value
.op
.op1
;
1339 op2
= e
->value
.op
.op2
;
1341 else if (e
->expr_type
== EXPR_FUNCTION
)
1343 /* One of the lexical comparison functions. */
1344 firstarg
= e
->value
.function
.actual
;
1345 secondarg
= firstarg
->next
;
1346 op1
= firstarg
->expr
;
1347 op2
= secondarg
->expr
;
1352 /* Strip off unneeded TRIM calls from string comparisons. */
1354 change
= remove_trim (op1
);
1356 if (remove_trim (op2
))
1359 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1360 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
1361 handles them well). However, there are also cases that need a non-scalar
1362 argument. For example the any intrinsic. See PR 45380. */
1366 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
1368 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
1369 && (op
== INTRINSIC_EQ
|| op
== INTRINSIC_NE
))
1371 bool empty_op1
, empty_op2
;
1372 empty_op1
= is_empty_string (op1
);
1373 empty_op2
= is_empty_string (op2
);
1375 if (empty_op1
|| empty_op2
)
1381 /* This can only happen when an error for comparing
1382 characters of different kinds has already been issued. */
1383 if (empty_op1
&& empty_op2
)
1386 zero
= gfc_get_int_expr (gfc_charlen_int_kind
, &e
->where
, 0);
1387 str
= empty_op1
? op2
: op1
;
1389 fcn
= get_len_trim_call (str
, gfc_charlen_int_kind
);
1393 gfc_free_expr (op1
);
1395 gfc_free_expr (op2
);
1399 e
->value
.op
.op1
= fcn
;
1400 e
->value
.op
.op2
= zero
;
1405 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
1407 if (flag_finite_math_only
1408 || (op1
->ts
.type
!= BT_REAL
&& op2
->ts
.type
!= BT_REAL
1409 && op1
->ts
.type
!= BT_COMPLEX
&& op2
->ts
.type
!= BT_COMPLEX
))
1411 eq
= gfc_dep_compare_expr (op1
, op2
);
1414 /* Replace A // B < A // C with B < C, and A // B < C // B
1416 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
1417 && op1
->expr_type
== EXPR_OP
1418 && op1
->value
.op
.op
== INTRINSIC_CONCAT
1419 && op2
->expr_type
== EXPR_OP
1420 && op2
->value
.op
.op
== INTRINSIC_CONCAT
)
1422 gfc_expr
*op1_left
= op1
->value
.op
.op1
;
1423 gfc_expr
*op2_left
= op2
->value
.op
.op1
;
1424 gfc_expr
*op1_right
= op1
->value
.op
.op2
;
1425 gfc_expr
*op2_right
= op2
->value
.op
.op2
;
1427 if (gfc_dep_compare_expr (op1_left
, op2_left
) == 0)
1429 /* Watch out for 'A ' // x vs. 'A' // x. */
1431 if (op1_left
->expr_type
== EXPR_CONSTANT
1432 && op2_left
->expr_type
== EXPR_CONSTANT
1433 && op1_left
->value
.character
.length
1434 != op2_left
->value
.character
.length
)
1442 firstarg
->expr
= op1_right
;
1443 secondarg
->expr
= op2_right
;
1447 e
->value
.op
.op1
= op1_right
;
1448 e
->value
.op
.op2
= op2_right
;
1450 optimize_comparison (e
, op
);
1454 if (gfc_dep_compare_expr (op1_right
, op2_right
) == 0)
1460 firstarg
->expr
= op1_left
;
1461 secondarg
->expr
= op2_left
;
1465 e
->value
.op
.op1
= op1_left
;
1466 e
->value
.op
.op2
= op2_left
;
1469 optimize_comparison (e
, op
);
1476 /* eq can only be -1, 0 or 1 at this point. */
1504 gfc_internal_error ("illegal OP in optimize_comparison");
1508 /* Replace the expression by a constant expression. The typespec
1509 and where remains the way it is. */
1512 e
->expr_type
= EXPR_CONSTANT
;
1513 e
->value
.logical
= result
;
1521 /* Optimize a trim function by replacing it with an equivalent substring
1522 involving a call to len_trim. This only works for expressions where
1523 variables are trimmed. Return true if anything was modified. */
1526 optimize_trim (gfc_expr
*e
)
1531 gfc_ref
**rr
= NULL
;
1533 /* Don't do this optimization within an argument list, because
1534 otherwise aliasing issues may occur. */
1536 if (count_arglist
!= 1)
1539 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_FUNCTION
1540 || e
->value
.function
.isym
== NULL
1541 || e
->value
.function
.isym
->id
!= GFC_ISYM_TRIM
)
1544 a
= e
->value
.function
.actual
->expr
;
1546 if (a
->expr_type
!= EXPR_VARIABLE
)
1549 /* Follow all references to find the correct place to put the newly
1550 created reference. FIXME: Also handle substring references and
1551 array references. Array references cause strange regressions at
1556 for (rr
= &(a
->ref
); *rr
; rr
= &((*rr
)->next
))
1558 if ((*rr
)->type
== REF_SUBSTRING
|| (*rr
)->type
== REF_ARRAY
)
1563 strip_function_call (e
);
1568 /* Create the reference. */
1570 ref
= gfc_get_ref ();
1571 ref
->type
= REF_SUBSTRING
;
1573 /* Set the start of the reference. */
1575 ref
->u
.ss
.start
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 1);
1577 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
1579 fcn
= get_len_trim_call (gfc_copy_expr (e
), gfc_default_integer_kind
);
1581 /* Set the end of the reference to the call to len_trim. */
1583 ref
->u
.ss
.end
= fcn
;
1584 gcc_assert (rr
!= NULL
&& *rr
== NULL
);
1589 /* Optimize minloc(b), where b is rank 1 array, into
1590 (/ minloc(b, dim=1) /), and similarly for maxloc,
1591 as the latter forms are expanded inline. */
1594 optimize_minmaxloc (gfc_expr
**e
)
1597 gfc_actual_arglist
*a
;
1601 || fn
->value
.function
.actual
== NULL
1602 || fn
->value
.function
.actual
->expr
== NULL
1603 || fn
->value
.function
.actual
->expr
->rank
!= 1)
1606 *e
= gfc_get_array_expr (fn
->ts
.type
, fn
->ts
.kind
, &fn
->where
);
1607 (*e
)->shape
= fn
->shape
;
1610 gfc_constructor_append_expr (&(*e
)->value
.constructor
, fn
, &fn
->where
);
1612 name
= XALLOCAVEC (char, strlen (fn
->value
.function
.name
) + 1);
1613 strcpy (name
, fn
->value
.function
.name
);
1614 p
= strstr (name
, "loc0");
1616 fn
->value
.function
.name
= gfc_get_string (name
);
1617 if (fn
->value
.function
.actual
->next
)
1619 a
= fn
->value
.function
.actual
->next
;
1620 gcc_assert (a
->expr
== NULL
);
1624 a
= gfc_get_actual_arglist ();
1625 fn
->value
.function
.actual
->next
= a
;
1627 a
->expr
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
1629 mpz_set_ui (a
->expr
->value
.integer
, 1);
1632 /* Callback function for code checking that we do not pass a DO variable to an
1633 INTENT(OUT) or INTENT(INOUT) dummy variable. */
1636 doloop_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1637 void *data ATTRIBUTE_UNUSED
)
1641 gfc_formal_arglist
*f
;
1642 gfc_actual_arglist
*a
;
1650 /* Grow the temporary storage if necessary. */
1651 if (doloop_level
>= doloop_size
)
1653 doloop_size
= 2 * doloop_size
;
1654 doloop_list
= XRESIZEVEC (gfc_code
*, doloop_list
, doloop_size
);
1657 /* Mark the DO loop variable if there is one. */
1658 if (co
->ext
.iterator
&& co
->ext
.iterator
->var
)
1659 doloop_list
[doloop_level
] = co
;
1661 doloop_list
[doloop_level
] = NULL
;
1666 if (co
->resolved_sym
== NULL
)
1669 f
= gfc_sym_get_dummy_args (co
->resolved_sym
);
1671 /* Withot a formal arglist, there is only unknown INTENT,
1672 which we don't check for. */
1680 for (i
=0; i
<doloop_level
; i
++)
1684 if (doloop_list
[i
] == NULL
)
1687 do_sym
= doloop_list
[i
]->ext
.iterator
->var
->symtree
->n
.sym
;
1689 if (a
->expr
&& a
->expr
->symtree
1690 && a
->expr
->symtree
->n
.sym
== do_sym
)
1692 if (f
->sym
->attr
.intent
== INTENT_OUT
)
1693 gfc_error_now("Variable '%s' at %L set to undefined value "
1694 "inside loop beginning at %L as INTENT(OUT) "
1695 "argument to subroutine '%s'", do_sym
->name
,
1696 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1697 co
->symtree
->n
.sym
->name
);
1698 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
1699 gfc_error_now("Variable '%s' at %L not definable inside loop "
1700 "beginning at %L as INTENT(INOUT) argument to "
1701 "subroutine '%s'", do_sym
->name
,
1702 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1703 co
->symtree
->n
.sym
->name
);
1717 /* Callback function for functions checking that we do not pass a DO variable
1718 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
1721 do_function (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1722 void *data ATTRIBUTE_UNUSED
)
1724 gfc_formal_arglist
*f
;
1725 gfc_actual_arglist
*a
;
1730 if (expr
->expr_type
!= EXPR_FUNCTION
)
1733 /* Intrinsic functions don't modify their arguments. */
1735 if (expr
->value
.function
.isym
)
1738 f
= gfc_sym_get_dummy_args (expr
->symtree
->n
.sym
);
1740 /* Without a formal arglist, there is only unknown INTENT,
1741 which we don't check for. */
1745 a
= expr
->value
.function
.actual
;
1749 for (i
=0; i
<doloop_level
; i
++)
1754 if (doloop_list
[i
] == NULL
)
1757 do_sym
= doloop_list
[i
]->ext
.iterator
->var
->symtree
->n
.sym
;
1759 if (a
->expr
&& a
->expr
->symtree
1760 && a
->expr
->symtree
->n
.sym
== do_sym
)
1762 if (f
->sym
->attr
.intent
== INTENT_OUT
)
1763 gfc_error_now("Variable '%s' at %L set to undefined value "
1764 "inside loop beginning at %L as INTENT(OUT) "
1765 "argument to function '%s'", do_sym
->name
,
1766 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1767 expr
->symtree
->n
.sym
->name
);
1768 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
1769 gfc_error_now("Variable '%s' at %L not definable inside loop "
1770 "beginning at %L as INTENT(INOUT) argument to "
1771 "function '%s'", do_sym
->name
,
1772 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1773 expr
->symtree
->n
.sym
->name
);
1784 doloop_warn (gfc_namespace
*ns
)
1786 gfc_code_walker (&ns
->code
, doloop_code
, do_function
, NULL
);
1790 #define WALK_SUBEXPR(NODE) \
1793 result = gfc_expr_walker (&(NODE), exprfn, data); \
1798 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
1800 /* Walk expression *E, calling EXPRFN on each expression in it. */
1803 gfc_expr_walker (gfc_expr
**e
, walk_expr_fn_t exprfn
, void *data
)
1807 int walk_subtrees
= 1;
1808 gfc_actual_arglist
*a
;
1812 int result
= exprfn (e
, &walk_subtrees
, data
);
1816 switch ((*e
)->expr_type
)
1819 WALK_SUBEXPR ((*e
)->value
.op
.op1
);
1820 WALK_SUBEXPR_TAIL ((*e
)->value
.op
.op2
);
1823 for (a
= (*e
)->value
.function
.actual
; a
; a
= a
->next
)
1824 WALK_SUBEXPR (a
->expr
);
1828 WALK_SUBEXPR ((*e
)->value
.compcall
.base_object
);
1829 for (a
= (*e
)->value
.compcall
.actual
; a
; a
= a
->next
)
1830 WALK_SUBEXPR (a
->expr
);
1833 case EXPR_STRUCTURE
:
1835 for (c
= gfc_constructor_first ((*e
)->value
.constructor
); c
;
1836 c
= gfc_constructor_next (c
))
1838 if (c
->iterator
== NULL
)
1839 WALK_SUBEXPR (c
->expr
);
1843 WALK_SUBEXPR (c
->expr
);
1845 WALK_SUBEXPR (c
->iterator
->var
);
1846 WALK_SUBEXPR (c
->iterator
->start
);
1847 WALK_SUBEXPR (c
->iterator
->end
);
1848 WALK_SUBEXPR (c
->iterator
->step
);
1852 if ((*e
)->expr_type
!= EXPR_ARRAY
)
1855 /* Fall through to the variable case in order to walk the
1858 case EXPR_SUBSTRING
:
1860 for (r
= (*e
)->ref
; r
; r
= r
->next
)
1869 if (ar
->type
== AR_SECTION
|| ar
->type
== AR_ELEMENT
)
1871 for (i
=0; i
< ar
->dimen
; i
++)
1873 WALK_SUBEXPR (ar
->start
[i
]);
1874 WALK_SUBEXPR (ar
->end
[i
]);
1875 WALK_SUBEXPR (ar
->stride
[i
]);
1882 WALK_SUBEXPR (r
->u
.ss
.start
);
1883 WALK_SUBEXPR (r
->u
.ss
.end
);
1899 #define WALK_SUBCODE(NODE) \
1902 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
1908 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
1909 on each expression in it. If any of the hooks returns non-zero, that
1910 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
1911 no subcodes or subexpressions are traversed. */
1914 gfc_code_walker (gfc_code
**c
, walk_code_fn_t codefn
, walk_expr_fn_t exprfn
,
1917 for (; *c
; c
= &(*c
)->next
)
1919 int walk_subtrees
= 1;
1920 int result
= codefn (c
, &walk_subtrees
, data
);
1927 gfc_actual_arglist
*a
;
1929 gfc_association_list
*alist
;
1930 bool saved_in_omp_workshare
;
1932 /* There might be statement insertions before the current code,
1933 which must not affect the expression walker. */
1936 saved_in_omp_workshare
= in_omp_workshare
;
1942 WALK_SUBCODE (co
->ext
.block
.ns
->code
);
1943 for (alist
= co
->ext
.block
.assoc
; alist
; alist
= alist
->next
)
1944 WALK_SUBEXPR (alist
->target
);
1949 WALK_SUBEXPR (co
->ext
.iterator
->var
);
1950 WALK_SUBEXPR (co
->ext
.iterator
->start
);
1951 WALK_SUBEXPR (co
->ext
.iterator
->end
);
1952 WALK_SUBEXPR (co
->ext
.iterator
->step
);
1956 case EXEC_ASSIGN_CALL
:
1957 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
1958 WALK_SUBEXPR (a
->expr
);
1962 WALK_SUBEXPR (co
->expr1
);
1963 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
1964 WALK_SUBEXPR (a
->expr
);
1968 WALK_SUBEXPR (co
->expr1
);
1969 for (b
= co
->block
; b
; b
= b
->block
)
1972 for (cp
= b
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
1974 WALK_SUBEXPR (cp
->low
);
1975 WALK_SUBEXPR (cp
->high
);
1977 WALK_SUBCODE (b
->next
);
1982 case EXEC_DEALLOCATE
:
1985 for (a
= co
->ext
.alloc
.list
; a
; a
= a
->next
)
1986 WALK_SUBEXPR (a
->expr
);
1991 case EXEC_DO_CONCURRENT
:
1993 gfc_forall_iterator
*fa
;
1994 for (fa
= co
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
1996 WALK_SUBEXPR (fa
->var
);
1997 WALK_SUBEXPR (fa
->start
);
1998 WALK_SUBEXPR (fa
->end
);
1999 WALK_SUBEXPR (fa
->stride
);
2001 if (co
->op
== EXEC_FORALL
)
2007 WALK_SUBEXPR (co
->ext
.open
->unit
);
2008 WALK_SUBEXPR (co
->ext
.open
->file
);
2009 WALK_SUBEXPR (co
->ext
.open
->status
);
2010 WALK_SUBEXPR (co
->ext
.open
->access
);
2011 WALK_SUBEXPR (co
->ext
.open
->form
);
2012 WALK_SUBEXPR (co
->ext
.open
->recl
);
2013 WALK_SUBEXPR (co
->ext
.open
->blank
);
2014 WALK_SUBEXPR (co
->ext
.open
->position
);
2015 WALK_SUBEXPR (co
->ext
.open
->action
);
2016 WALK_SUBEXPR (co
->ext
.open
->delim
);
2017 WALK_SUBEXPR (co
->ext
.open
->pad
);
2018 WALK_SUBEXPR (co
->ext
.open
->iostat
);
2019 WALK_SUBEXPR (co
->ext
.open
->iomsg
);
2020 WALK_SUBEXPR (co
->ext
.open
->convert
);
2021 WALK_SUBEXPR (co
->ext
.open
->decimal
);
2022 WALK_SUBEXPR (co
->ext
.open
->encoding
);
2023 WALK_SUBEXPR (co
->ext
.open
->round
);
2024 WALK_SUBEXPR (co
->ext
.open
->sign
);
2025 WALK_SUBEXPR (co
->ext
.open
->asynchronous
);
2026 WALK_SUBEXPR (co
->ext
.open
->id
);
2027 WALK_SUBEXPR (co
->ext
.open
->newunit
);
2031 WALK_SUBEXPR (co
->ext
.close
->unit
);
2032 WALK_SUBEXPR (co
->ext
.close
->status
);
2033 WALK_SUBEXPR (co
->ext
.close
->iostat
);
2034 WALK_SUBEXPR (co
->ext
.close
->iomsg
);
2037 case EXEC_BACKSPACE
:
2041 WALK_SUBEXPR (co
->ext
.filepos
->unit
);
2042 WALK_SUBEXPR (co
->ext
.filepos
->iostat
);
2043 WALK_SUBEXPR (co
->ext
.filepos
->iomsg
);
2047 WALK_SUBEXPR (co
->ext
.inquire
->unit
);
2048 WALK_SUBEXPR (co
->ext
.inquire
->file
);
2049 WALK_SUBEXPR (co
->ext
.inquire
->iomsg
);
2050 WALK_SUBEXPR (co
->ext
.inquire
->iostat
);
2051 WALK_SUBEXPR (co
->ext
.inquire
->exist
);
2052 WALK_SUBEXPR (co
->ext
.inquire
->opened
);
2053 WALK_SUBEXPR (co
->ext
.inquire
->number
);
2054 WALK_SUBEXPR (co
->ext
.inquire
->named
);
2055 WALK_SUBEXPR (co
->ext
.inquire
->name
);
2056 WALK_SUBEXPR (co
->ext
.inquire
->access
);
2057 WALK_SUBEXPR (co
->ext
.inquire
->sequential
);
2058 WALK_SUBEXPR (co
->ext
.inquire
->direct
);
2059 WALK_SUBEXPR (co
->ext
.inquire
->form
);
2060 WALK_SUBEXPR (co
->ext
.inquire
->formatted
);
2061 WALK_SUBEXPR (co
->ext
.inquire
->unformatted
);
2062 WALK_SUBEXPR (co
->ext
.inquire
->recl
);
2063 WALK_SUBEXPR (co
->ext
.inquire
->nextrec
);
2064 WALK_SUBEXPR (co
->ext
.inquire
->blank
);
2065 WALK_SUBEXPR (co
->ext
.inquire
->position
);
2066 WALK_SUBEXPR (co
->ext
.inquire
->action
);
2067 WALK_SUBEXPR (co
->ext
.inquire
->read
);
2068 WALK_SUBEXPR (co
->ext
.inquire
->write
);
2069 WALK_SUBEXPR (co
->ext
.inquire
->readwrite
);
2070 WALK_SUBEXPR (co
->ext
.inquire
->delim
);
2071 WALK_SUBEXPR (co
->ext
.inquire
->encoding
);
2072 WALK_SUBEXPR (co
->ext
.inquire
->pad
);
2073 WALK_SUBEXPR (co
->ext
.inquire
->iolength
);
2074 WALK_SUBEXPR (co
->ext
.inquire
->convert
);
2075 WALK_SUBEXPR (co
->ext
.inquire
->strm_pos
);
2076 WALK_SUBEXPR (co
->ext
.inquire
->asynchronous
);
2077 WALK_SUBEXPR (co
->ext
.inquire
->decimal
);
2078 WALK_SUBEXPR (co
->ext
.inquire
->pending
);
2079 WALK_SUBEXPR (co
->ext
.inquire
->id
);
2080 WALK_SUBEXPR (co
->ext
.inquire
->sign
);
2081 WALK_SUBEXPR (co
->ext
.inquire
->size
);
2082 WALK_SUBEXPR (co
->ext
.inquire
->round
);
2086 WALK_SUBEXPR (co
->ext
.wait
->unit
);
2087 WALK_SUBEXPR (co
->ext
.wait
->iostat
);
2088 WALK_SUBEXPR (co
->ext
.wait
->iomsg
);
2089 WALK_SUBEXPR (co
->ext
.wait
->id
);
2094 WALK_SUBEXPR (co
->ext
.dt
->io_unit
);
2095 WALK_SUBEXPR (co
->ext
.dt
->format_expr
);
2096 WALK_SUBEXPR (co
->ext
.dt
->rec
);
2097 WALK_SUBEXPR (co
->ext
.dt
->advance
);
2098 WALK_SUBEXPR (co
->ext
.dt
->iostat
);
2099 WALK_SUBEXPR (co
->ext
.dt
->size
);
2100 WALK_SUBEXPR (co
->ext
.dt
->iomsg
);
2101 WALK_SUBEXPR (co
->ext
.dt
->id
);
2102 WALK_SUBEXPR (co
->ext
.dt
->pos
);
2103 WALK_SUBEXPR (co
->ext
.dt
->asynchronous
);
2104 WALK_SUBEXPR (co
->ext
.dt
->blank
);
2105 WALK_SUBEXPR (co
->ext
.dt
->decimal
);
2106 WALK_SUBEXPR (co
->ext
.dt
->delim
);
2107 WALK_SUBEXPR (co
->ext
.dt
->pad
);
2108 WALK_SUBEXPR (co
->ext
.dt
->round
);
2109 WALK_SUBEXPR (co
->ext
.dt
->sign
);
2110 WALK_SUBEXPR (co
->ext
.dt
->extra_comma
);
2113 case EXEC_OMP_PARALLEL
:
2114 case EXEC_OMP_PARALLEL_DO
:
2115 case EXEC_OMP_PARALLEL_SECTIONS
:
2117 in_omp_workshare
= false;
2119 /* This goto serves as a shortcut to avoid code
2120 duplication or a larger if or switch statement. */
2121 goto check_omp_clauses
;
2123 case EXEC_OMP_WORKSHARE
:
2124 case EXEC_OMP_PARALLEL_WORKSHARE
:
2126 in_omp_workshare
= true;
2131 case EXEC_OMP_SECTIONS
:
2132 case EXEC_OMP_SINGLE
:
2133 case EXEC_OMP_END_SINGLE
:
2136 /* Come to this label only from the
2137 EXEC_OMP_PARALLEL_* cases above. */
2141 if (co
->ext
.omp_clauses
)
2143 WALK_SUBEXPR (co
->ext
.omp_clauses
->if_expr
);
2144 WALK_SUBEXPR (co
->ext
.omp_clauses
->final_expr
);
2145 WALK_SUBEXPR (co
->ext
.omp_clauses
->num_threads
);
2146 WALK_SUBEXPR (co
->ext
.omp_clauses
->chunk_size
);
2153 WALK_SUBEXPR (co
->expr1
);
2154 WALK_SUBEXPR (co
->expr2
);
2155 WALK_SUBEXPR (co
->expr3
);
2156 WALK_SUBEXPR (co
->expr4
);
2157 for (b
= co
->block
; b
; b
= b
->block
)
2159 WALK_SUBEXPR (b
->expr1
);
2160 WALK_SUBEXPR (b
->expr2
);
2161 WALK_SUBCODE (b
->next
);
2164 if (co
->op
== EXEC_FORALL
)
2167 if (co
->op
== EXEC_DO
)
2170 in_omp_workshare
= saved_in_omp_workshare
;