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
)
138 if (op
== EXEC_ASSIGN
)
139 optimize_assignment (*c
);
143 /* Callback for each gfc_expr node invoked through gfc_code_walker
144 from optimize_namespace. */
147 optimize_expr (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
148 void *data ATTRIBUTE_UNUSED
)
152 if ((*e
)->expr_type
== EXPR_FUNCTION
)
155 function_expr
= true;
158 function_expr
= false;
160 if (optimize_trim (*e
))
161 gfc_simplify_expr (*e
, 0);
163 if (optimize_lexical_comparison (*e
))
164 gfc_simplify_expr (*e
, 0);
166 if ((*e
)->expr_type
== EXPR_OP
&& optimize_op (*e
))
167 gfc_simplify_expr (*e
, 0);
169 if ((*e
)->expr_type
== EXPR_FUNCTION
&& (*e
)->value
.function
.isym
)
170 switch ((*e
)->value
.function
.isym
->id
)
172 case GFC_ISYM_MINLOC
:
173 case GFC_ISYM_MAXLOC
:
174 optimize_minmaxloc (e
);
186 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
187 function is a scalar, just copy it; otherwise returns the new element, the
188 old one can be freed. */
191 copy_walk_reduction_arg (gfc_expr
*e
, gfc_expr
*fn
)
196 if (e
->rank
== 0 || e
->expr_type
== EXPR_FUNCTION
)
197 fcn
= gfc_copy_expr (e
);
200 id
= fn
->value
.function
.isym
->id
;
202 if (id
== GFC_ISYM_SUM
|| id
== GFC_ISYM_PRODUCT
)
203 fcn
= gfc_build_intrinsic_call (current_ns
,
204 fn
->value
.function
.isym
->id
,
205 fn
->value
.function
.isym
->name
,
206 fn
->where
, 3, gfc_copy_expr (e
),
208 else if (id
== GFC_ISYM_ANY
|| id
== GFC_ISYM_ALL
)
209 fcn
= gfc_build_intrinsic_call (current_ns
,
210 fn
->value
.function
.isym
->id
,
211 fn
->value
.function
.isym
->name
,
212 fn
->where
, 2, gfc_copy_expr (e
),
215 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
217 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
220 (void) gfc_expr_walker (&fcn
, callback_reduction
, NULL
);
225 /* Callback function for optimzation of reductions to scalars. Transform ANY
226 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
227 correspondingly. Handly only the simple cases without MASK and DIM. */
230 callback_reduction (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
231 void *data ATTRIBUTE_UNUSED
)
236 gfc_actual_arglist
*a
;
237 gfc_actual_arglist
*dim
;
239 gfc_expr
*res
, *new_expr
;
240 gfc_actual_arglist
*mask
;
244 if (fn
->rank
!= 0 || fn
->expr_type
!= EXPR_FUNCTION
245 || fn
->value
.function
.isym
== NULL
)
248 id
= fn
->value
.function
.isym
->id
;
250 if (id
!= GFC_ISYM_SUM
&& id
!= GFC_ISYM_PRODUCT
251 && id
!= GFC_ISYM_ANY
&& id
!= GFC_ISYM_ALL
)
254 a
= fn
->value
.function
.actual
;
256 /* Don't handle MASK or DIM. */
260 if (dim
->expr
!= NULL
)
263 if (id
== GFC_ISYM_SUM
|| id
== GFC_ISYM_PRODUCT
)
266 if ( mask
->expr
!= NULL
)
272 if (arg
->expr_type
!= EXPR_ARRAY
)
281 case GFC_ISYM_PRODUCT
:
282 op
= INTRINSIC_TIMES
;
297 c
= gfc_constructor_first (arg
->value
.constructor
);
302 res
= copy_walk_reduction_arg (c
->expr
, fn
);
304 c
= gfc_constructor_next (c
);
307 new_expr
= gfc_get_expr ();
308 new_expr
->ts
= fn
->ts
;
309 new_expr
->expr_type
= EXPR_OP
;
310 new_expr
->rank
= fn
->rank
;
311 new_expr
->where
= fn
->where
;
312 new_expr
->value
.op
.op
= op
;
313 new_expr
->value
.op
.op1
= res
;
314 new_expr
->value
.op
.op2
= copy_walk_reduction_arg (c
->expr
, fn
);
316 c
= gfc_constructor_next (c
);
319 gfc_simplify_expr (res
, 0);
326 /* Callback function for common function elimination, called from cfe_expr_0.
327 Put all eligible function expressions into expr_array. */
330 cfe_register_funcs (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
331 void *data ATTRIBUTE_UNUSED
)
334 if ((*e
)->expr_type
!= EXPR_FUNCTION
)
337 /* We don't do character functions with unknown charlens. */
338 if ((*e
)->ts
.type
== BT_CHARACTER
339 && ((*e
)->ts
.u
.cl
== NULL
|| (*e
)->ts
.u
.cl
->length
== NULL
340 || (*e
)->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
))
343 /* We don't do function elimination within FORALL statements, it can
344 lead to wrong-code in certain circumstances. */
346 if (forall_level
> 0)
349 /* Function elimination inside an iterator could lead to functions which
350 depend on iterator variables being moved outside. FIXME: We should check
351 if the functions do indeed depend on the iterator variable. */
353 if (iterator_level
> 0)
356 /* If we don't know the shape at compile time, we create an allocatable
357 temporary variable to hold the intermediate result, but only if
358 allocation on assignment is active. */
360 if ((*e
)->rank
> 0 && (*e
)->shape
== NULL
&& !gfc_option
.flag_realloc_lhs
)
363 /* Skip the test for pure functions if -faggressive-function-elimination
365 if ((*e
)->value
.function
.esym
)
367 /* Don't create an array temporary for elemental functions. */
368 if ((*e
)->value
.function
.esym
->attr
.elemental
&& (*e
)->rank
> 0)
371 /* Only eliminate potentially impure functions if the
372 user specifically requested it. */
373 if (!gfc_option
.flag_aggressive_function_elimination
374 && !(*e
)->value
.function
.esym
->attr
.pure
375 && !(*e
)->value
.function
.esym
->attr
.implicit_pure
)
379 if ((*e
)->value
.function
.isym
)
381 /* Conversions are handled on the fly by the middle end,
382 transpose during trans-* stages and TRANSFER by the middle end. */
383 if ((*e
)->value
.function
.isym
->id
== GFC_ISYM_CONVERSION
384 || (*e
)->value
.function
.isym
->id
== GFC_ISYM_TRANSFER
385 || gfc_inline_intrinsic_function_p (*e
))
388 /* Don't create an array temporary for elemental functions,
389 as this would be wasteful of memory.
390 FIXME: Create a scalar temporary during scalarization. */
391 if ((*e
)->value
.function
.isym
->elemental
&& (*e
)->rank
> 0)
394 if (!(*e
)->value
.function
.isym
->pure
)
398 if (expr_count
>= expr_size
)
400 expr_size
+= expr_size
;
401 expr_array
= XRESIZEVEC(gfc_expr
**, expr_array
, expr_size
);
403 expr_array
[expr_count
] = e
;
408 /* Returns a new expression (a variable) to be used in place of the old one,
409 with an assignment statement before the current statement to set
410 the value of the variable. Creates a new BLOCK for the statement if
411 that hasn't already been done and puts the statement, plus the
412 newly created variables, in that block. */
415 create_var (gfc_expr
* e
)
417 char name
[GFC_MAX_SYMBOL_LEN
+1];
419 gfc_symtree
*symtree
;
426 /* If the block hasn't already been created, do so. */
427 if (inserted_block
== NULL
)
429 inserted_block
= XCNEW (gfc_code
);
430 inserted_block
->op
= EXEC_BLOCK
;
431 inserted_block
->loc
= (*current_code
)->loc
;
432 ns
= gfc_build_block_ns (current_ns
);
433 inserted_block
->ext
.block
.ns
= ns
;
434 inserted_block
->ext
.block
.assoc
= NULL
;
436 ns
->code
= *current_code
;
438 /* If the statement has a label, make sure it is transferred to
439 the newly created block. */
441 if ((*current_code
)->here
)
443 inserted_block
->here
= (*current_code
)->here
;
444 (*current_code
)->here
= NULL
;
447 inserted_block
->next
= (*current_code
)->next
;
448 changed_statement
= &(inserted_block
->ext
.block
.ns
->code
);
449 (*current_code
)->next
= NULL
;
450 /* Insert the BLOCK at the right position. */
451 *current_code
= inserted_block
;
452 ns
->parent
= current_ns
;
455 ns
= inserted_block
->ext
.block
.ns
;
457 sprintf(name
, "__var_%d",num
++);
458 if (gfc_get_sym_tree (name
, ns
, &symtree
, false) != 0)
461 symbol
= symtree
->n
.sym
;
466 symbol
->as
= gfc_get_array_spec ();
467 symbol
->as
->rank
= e
->rank
;
469 if (e
->shape
== NULL
)
471 /* We don't know the shape at compile time, so we use an
473 symbol
->as
->type
= AS_DEFERRED
;
474 symbol
->attr
.allocatable
= 1;
478 symbol
->as
->type
= AS_EXPLICIT
;
479 /* Copy the shape. */
480 for (i
=0; i
<e
->rank
; i
++)
484 p
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
486 mpz_set_si (p
->value
.integer
, 1);
487 symbol
->as
->lower
[i
] = p
;
489 q
= gfc_get_constant_expr (BT_INTEGER
, gfc_index_integer_kind
,
491 mpz_set (q
->value
.integer
, e
->shape
[i
]);
492 symbol
->as
->upper
[i
] = q
;
497 symbol
->attr
.flavor
= FL_VARIABLE
;
498 symbol
->attr
.referenced
= 1;
499 symbol
->attr
.dimension
= e
->rank
> 0;
500 gfc_commit_symbol (symbol
);
502 result
= gfc_get_expr ();
503 result
->expr_type
= EXPR_VARIABLE
;
505 result
->rank
= e
->rank
;
506 result
->shape
= gfc_copy_shape (e
->shape
, e
->rank
);
507 result
->symtree
= symtree
;
508 result
->where
= e
->where
;
511 result
->ref
= gfc_get_ref ();
512 result
->ref
->type
= REF_ARRAY
;
513 result
->ref
->u
.ar
.type
= AR_FULL
;
514 result
->ref
->u
.ar
.where
= e
->where
;
515 result
->ref
->u
.ar
.as
= symbol
->ts
.type
== BT_CLASS
516 ? CLASS_DATA (symbol
)->as
: symbol
->as
;
517 if (gfc_option
.warn_array_temp
)
518 gfc_warning ("Creating array temporary at %L", &(e
->where
));
521 /* Generate the new assignment. */
522 n
= XCNEW (gfc_code
);
524 n
->loc
= (*current_code
)->loc
;
525 n
->next
= *changed_statement
;
526 n
->expr1
= gfc_copy_expr (result
);
528 *changed_statement
= n
;
533 /* Warn about function elimination. */
536 warn_function_elimination (gfc_expr
*e
)
538 if (e
->expr_type
!= EXPR_FUNCTION
)
540 if (e
->value
.function
.esym
)
541 gfc_warning ("Removing call to function '%s' at %L",
542 e
->value
.function
.esym
->name
, &(e
->where
));
543 else if (e
->value
.function
.isym
)
544 gfc_warning ("Removing call to function '%s' at %L",
545 e
->value
.function
.isym
->name
, &(e
->where
));
547 /* Callback function for the code walker for doing common function
548 elimination. This builds up the list of functions in the expression
549 and goes through them to detect duplicates, which it then replaces
553 cfe_expr_0 (gfc_expr
**e
, int *walk_subtrees
,
554 void *data ATTRIBUTE_UNUSED
)
559 /* Don't do this optimization within OMP workshare. */
561 if (in_omp_workshare
)
569 gfc_expr_walker (e
, cfe_register_funcs
, NULL
);
571 /* Walk through all the functions. */
573 for (i
=1; i
<expr_count
; i
++)
575 /* Skip if the function has been replaced by a variable already. */
576 if ((*(expr_array
[i
]))->expr_type
== EXPR_VARIABLE
)
582 if (gfc_dep_compare_functions(*(expr_array
[i
]),
583 *(expr_array
[j
]), true) == 0)
586 newvar
= create_var (*(expr_array
[i
]));
588 if (gfc_option
.warn_function_elimination
)
589 warn_function_elimination (*(expr_array
[j
]));
591 free (*(expr_array
[j
]));
592 *(expr_array
[j
]) = gfc_copy_expr (newvar
);
596 *(expr_array
[i
]) = newvar
;
599 /* We did all the necessary walking in this function. */
604 /* Callback function for common function elimination, called from
605 gfc_code_walker. This keeps track of the current code, in order
606 to insert statements as needed. */
609 cfe_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
610 void *data ATTRIBUTE_UNUSED
)
613 inserted_block
= NULL
;
614 changed_statement
= NULL
;
618 /* Dummy function for expression call back, for use when we
619 really don't want to do any walking. */
622 dummy_expr_callback (gfc_expr
**e ATTRIBUTE_UNUSED
, int *walk_subtrees
,
623 void *data ATTRIBUTE_UNUSED
)
629 /* Dummy function for code callback, for use when we really
630 don't want to do anything. */
632 dummy_code_callback (gfc_code
**e ATTRIBUTE_UNUSED
,
633 int *walk_subtrees ATTRIBUTE_UNUSED
,
634 void *data ATTRIBUTE_UNUSED
)
639 /* Code callback function for converting
646 This is because common function elimination would otherwise place the
647 temporary variables outside the loop. */
650 convert_do_while (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
651 void *data ATTRIBUTE_UNUSED
)
654 gfc_code
*c_if1
, *c_if2
, *c_exit
;
656 gfc_expr
*e_not
, *e_cond
;
658 if (co
->op
!= EXEC_DO_WHILE
)
661 if (co
->expr1
== NULL
|| co
->expr1
->expr_type
== EXPR_CONSTANT
)
666 /* Generate the condition of the if statement, which is .not. the original
668 e_not
= gfc_get_expr ();
669 e_not
->ts
= e_cond
->ts
;
670 e_not
->where
= e_cond
->where
;
671 e_not
->expr_type
= EXPR_OP
;
672 e_not
->value
.op
.op
= INTRINSIC_NOT
;
673 e_not
->value
.op
.op1
= e_cond
;
675 /* Generate the EXIT statement. */
676 c_exit
= XCNEW (gfc_code
);
677 c_exit
->op
= EXEC_EXIT
;
678 c_exit
->ext
.which_construct
= co
;
679 c_exit
->loc
= co
->loc
;
681 /* Generate the IF statement. */
682 c_if2
= XCNEW (gfc_code
);
684 c_if2
->expr1
= e_not
;
685 c_if2
->next
= c_exit
;
686 c_if2
->loc
= co
->loc
;
688 /* ... plus the one to chain it to. */
689 c_if1
= XCNEW (gfc_code
);
691 c_if1
->block
= c_if2
;
692 c_if1
->loc
= co
->loc
;
694 /* Make the DO WHILE loop into a DO block by replacing the condition
695 with a true constant. */
696 co
->expr1
= gfc_get_logical_expr (gfc_default_integer_kind
, &co
->loc
, true);
698 /* Hang the generated if statement into the loop body. */
700 loopblock
= co
->block
->next
;
701 co
->block
->next
= c_if1
;
702 c_if1
->next
= loopblock
;
707 /* Code callback function for converting
720 because otherwise common function elimination would place the BLOCKs
721 into the wrong place. */
724 convert_elseif (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
725 void *data ATTRIBUTE_UNUSED
)
728 gfc_code
*c_if1
, *c_if2
, *else_stmt
;
730 if (co
->op
!= EXEC_IF
)
733 /* This loop starts out with the first ELSE statement. */
734 else_stmt
= co
->block
->block
;
736 while (else_stmt
!= NULL
)
740 /* If there is no condition, we're done. */
741 if (else_stmt
->expr1
== NULL
)
744 next_else
= else_stmt
->block
;
746 /* Generate the new IF statement. */
747 c_if2
= XCNEW (gfc_code
);
749 c_if2
->expr1
= else_stmt
->expr1
;
750 c_if2
->next
= else_stmt
->next
;
751 c_if2
->loc
= else_stmt
->loc
;
752 c_if2
->block
= next_else
;
754 /* ... plus the one to chain it to. */
755 c_if1
= XCNEW (gfc_code
);
757 c_if1
->block
= c_if2
;
758 c_if1
->loc
= else_stmt
->loc
;
760 /* Insert the new IF after the ELSE. */
761 else_stmt
->expr1
= NULL
;
762 else_stmt
->next
= c_if1
;
763 else_stmt
->block
= NULL
;
765 else_stmt
= next_else
;
767 /* Don't walk subtrees. */
770 /* Optimize a namespace, including all contained namespaces. */
773 optimize_namespace (gfc_namespace
*ns
)
779 in_omp_workshare
= false;
781 gfc_code_walker (&ns
->code
, convert_do_while
, dummy_expr_callback
, NULL
);
782 gfc_code_walker (&ns
->code
, convert_elseif
, dummy_expr_callback
, NULL
);
783 gfc_code_walker (&ns
->code
, cfe_code
, cfe_expr_0
, NULL
);
784 gfc_code_walker (&ns
->code
, optimize_code
, optimize_expr
, NULL
);
786 /* BLOCKs are handled in the expression walker below. */
787 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
789 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
790 optimize_namespace (ns
);
795 optimize_reduction (gfc_namespace
*ns
)
798 gfc_code_walker (&ns
->code
, dummy_code_callback
, callback_reduction
, NULL
);
800 /* BLOCKs are handled in the expression walker below. */
801 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
803 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
804 optimize_reduction (ns
);
811 a = matmul(b,c) ; a = a + d
812 where the array function is not elemental and not allocatable
813 and does not depend on the left-hand side.
817 optimize_binop_array_assignment (gfc_code
*c
, gfc_expr
**rhs
, bool seen_op
)
822 if (e
->expr_type
== EXPR_OP
)
824 switch (e
->value
.op
.op
)
826 /* Unary operators and exponentiation: Only look at a single
829 case INTRINSIC_UPLUS
:
830 case INTRINSIC_UMINUS
:
831 case INTRINSIC_PARENTHESES
:
832 case INTRINSIC_POWER
:
833 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, seen_op
))
838 /* Binary operators. */
839 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, true))
842 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op2
, true))
848 else if (seen_op
&& e
->expr_type
== EXPR_FUNCTION
&& e
->rank
> 0
849 && ! (e
->value
.function
.esym
850 && (e
->value
.function
.esym
->attr
.elemental
851 || e
->value
.function
.esym
->attr
.allocatable
852 || e
->value
.function
.esym
->ts
.type
!= c
->expr1
->ts
.type
853 || e
->value
.function
.esym
->ts
.kind
!= c
->expr1
->ts
.kind
))
854 && ! (e
->value
.function
.isym
855 && (e
->value
.function
.isym
->elemental
856 || e
->ts
.type
!= c
->expr1
->ts
.type
857 || e
->ts
.kind
!= c
->expr1
->ts
.kind
))
858 && ! gfc_inline_intrinsic_function_p (e
))
864 /* Insert a new assignment statement after the current one. */
865 n
= XCNEW (gfc_code
);
871 n
->expr1
= gfc_copy_expr (c
->expr1
);
873 new_expr
= gfc_copy_expr (c
->expr1
);
881 /* Nothing to optimize. */
885 /* Remove unneeded TRIMs at the end of expressions. */
888 remove_trim (gfc_expr
*rhs
)
894 /* Check for a // b // trim(c). Looping is probably not
895 necessary because the parser usually generates
896 (// (// a b ) trim(c) ) , but better safe than sorry. */
898 while (rhs
->expr_type
== EXPR_OP
899 && rhs
->value
.op
.op
== INTRINSIC_CONCAT
)
900 rhs
= rhs
->value
.op
.op2
;
902 while (rhs
->expr_type
== EXPR_FUNCTION
&& rhs
->value
.function
.isym
903 && rhs
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
905 strip_function_call (rhs
);
906 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
914 /* Optimizations for an assignment. */
917 optimize_assignment (gfc_code
* c
)
924 if (lhs
->ts
.type
== BT_CHARACTER
&& !lhs
->ts
.deferred
)
926 /* Optimize a = trim(b) to a = b. */
929 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
930 if (is_empty_string(rhs
))
931 rhs
->value
.character
.length
= 0;
934 if (lhs
->rank
> 0 && gfc_check_dependency (lhs
, rhs
, true) == 0)
935 optimize_binop_array_assignment (c
, &rhs
, false);
939 /* Remove an unneeded function call, modifying the expression.
940 This replaces the function call with the value of its
941 first argument. The rest of the argument list is freed. */
944 strip_function_call (gfc_expr
*e
)
947 gfc_actual_arglist
*a
;
949 a
= e
->value
.function
.actual
;
951 /* We should have at least one argument. */
952 gcc_assert (a
->expr
!= NULL
);
956 /* Free the remaining arglist, if any. */
958 gfc_free_actual_arglist (a
->next
);
960 /* Graft the argument expression onto the original function. */
966 /* Optimization of lexical comparison functions. */
969 optimize_lexical_comparison (gfc_expr
*e
)
971 if (e
->expr_type
!= EXPR_FUNCTION
|| e
->value
.function
.isym
== NULL
)
974 switch (e
->value
.function
.isym
->id
)
977 return optimize_comparison (e
, INTRINSIC_LE
);
980 return optimize_comparison (e
, INTRINSIC_GE
);
983 return optimize_comparison (e
, INTRINSIC_GT
);
986 return optimize_comparison (e
, INTRINSIC_LT
);
994 /* Recursive optimization of operators. */
997 optimize_op (gfc_expr
*e
)
999 gfc_intrinsic_op op
= e
->value
.op
.op
;
1001 /* Only use new-style comparisons. */
1004 case INTRINSIC_EQ_OS
:
1008 case INTRINSIC_GE_OS
:
1012 case INTRINSIC_LE_OS
:
1016 case INTRINSIC_NE_OS
:
1020 case INTRINSIC_GT_OS
:
1024 case INTRINSIC_LT_OS
:
1040 return optimize_comparison (e
, op
);
1050 /* Return true if a constant string contains only blanks. */
1053 is_empty_string (gfc_expr
*e
)
1057 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_CONSTANT
)
1060 for (i
=0; i
< e
->value
.character
.length
; i
++)
1062 if (e
->value
.character
.string
[i
] != ' ')
1070 /* Insert a call to the intrinsic len_trim. Use a different name for
1071 the symbol tree so we don't run into trouble when the user has
1072 renamed len_trim for some reason. */
1075 get_len_trim_call (gfc_expr
*str
, int kind
)
1078 gfc_actual_arglist
*actual_arglist
, *next
;
1080 fcn
= gfc_get_expr ();
1081 fcn
->expr_type
= EXPR_FUNCTION
;
1082 fcn
->value
.function
.isym
= gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM
);
1083 actual_arglist
= gfc_get_actual_arglist ();
1084 actual_arglist
->expr
= str
;
1085 next
= gfc_get_actual_arglist ();
1086 next
->expr
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, kind
);
1087 actual_arglist
->next
= next
;
1089 fcn
->value
.function
.actual
= actual_arglist
;
1090 fcn
->where
= str
->where
;
1091 fcn
->ts
.type
= BT_INTEGER
;
1092 fcn
->ts
.kind
= gfc_charlen_int_kind
;
1094 gfc_get_sym_tree ("__internal_len_trim", current_ns
, &fcn
->symtree
, false);
1095 fcn
->symtree
->n
.sym
->ts
= fcn
->ts
;
1096 fcn
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
1097 fcn
->symtree
->n
.sym
->attr
.function
= 1;
1098 fcn
->symtree
->n
.sym
->attr
.elemental
= 1;
1099 fcn
->symtree
->n
.sym
->attr
.referenced
= 1;
1100 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
1101 gfc_commit_symbol (fcn
->symtree
->n
.sym
);
1106 /* Optimize expressions for equality. */
1109 optimize_comparison (gfc_expr
*e
, gfc_intrinsic_op op
)
1111 gfc_expr
*op1
, *op2
;
1115 gfc_actual_arglist
*firstarg
, *secondarg
;
1117 if (e
->expr_type
== EXPR_OP
)
1121 op1
= e
->value
.op
.op1
;
1122 op2
= e
->value
.op
.op2
;
1124 else if (e
->expr_type
== EXPR_FUNCTION
)
1126 /* One of the lexical comparison functions. */
1127 firstarg
= e
->value
.function
.actual
;
1128 secondarg
= firstarg
->next
;
1129 op1
= firstarg
->expr
;
1130 op2
= secondarg
->expr
;
1135 /* Strip off unneeded TRIM calls from string comparisons. */
1137 change
= remove_trim (op1
);
1139 if (remove_trim (op2
))
1142 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1143 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
1144 handles them well). However, there are also cases that need a non-scalar
1145 argument. For example the any intrinsic. See PR 45380. */
1149 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
1151 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
1152 && (op
== INTRINSIC_EQ
|| op
== INTRINSIC_NE
))
1154 bool empty_op1
, empty_op2
;
1155 empty_op1
= is_empty_string (op1
);
1156 empty_op2
= is_empty_string (op2
);
1158 if (empty_op1
|| empty_op2
)
1164 /* This can only happen when an error for comparing
1165 characters of different kinds has already been issued. */
1166 if (empty_op1
&& empty_op2
)
1169 zero
= gfc_get_int_expr (gfc_charlen_int_kind
, &e
->where
, 0);
1170 str
= empty_op1
? op2
: op1
;
1172 fcn
= get_len_trim_call (str
, gfc_charlen_int_kind
);
1176 gfc_free_expr (op1
);
1178 gfc_free_expr (op2
);
1182 e
->value
.op
.op1
= fcn
;
1183 e
->value
.op
.op2
= zero
;
1188 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
1190 if (flag_finite_math_only
1191 || (op1
->ts
.type
!= BT_REAL
&& op2
->ts
.type
!= BT_REAL
1192 && op1
->ts
.type
!= BT_COMPLEX
&& op2
->ts
.type
!= BT_COMPLEX
))
1194 eq
= gfc_dep_compare_expr (op1
, op2
);
1197 /* Replace A // B < A // C with B < C, and A // B < C // B
1199 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
1200 && op1
->value
.op
.op
== INTRINSIC_CONCAT
1201 && op2
->value
.op
.op
== INTRINSIC_CONCAT
)
1203 gfc_expr
*op1_left
= op1
->value
.op
.op1
;
1204 gfc_expr
*op2_left
= op2
->value
.op
.op1
;
1205 gfc_expr
*op1_right
= op1
->value
.op
.op2
;
1206 gfc_expr
*op2_right
= op2
->value
.op
.op2
;
1208 if (gfc_dep_compare_expr (op1_left
, op2_left
) == 0)
1210 /* Watch out for 'A ' // x vs. 'A' // x. */
1212 if (op1_left
->expr_type
== EXPR_CONSTANT
1213 && op2_left
->expr_type
== EXPR_CONSTANT
1214 && op1_left
->value
.character
.length
1215 != op2_left
->value
.character
.length
)
1223 firstarg
->expr
= op1_right
;
1224 secondarg
->expr
= op2_right
;
1228 e
->value
.op
.op1
= op1_right
;
1229 e
->value
.op
.op2
= op2_right
;
1231 optimize_comparison (e
, op
);
1235 if (gfc_dep_compare_expr (op1_right
, op2_right
) == 0)
1241 firstarg
->expr
= op1_left
;
1242 secondarg
->expr
= op2_left
;
1246 e
->value
.op
.op1
= op1_left
;
1247 e
->value
.op
.op2
= op2_left
;
1250 optimize_comparison (e
, op
);
1257 /* eq can only be -1, 0 or 1 at this point. */
1285 gfc_internal_error ("illegal OP in optimize_comparison");
1289 /* Replace the expression by a constant expression. The typespec
1290 and where remains the way it is. */
1293 e
->expr_type
= EXPR_CONSTANT
;
1294 e
->value
.logical
= result
;
1302 /* Optimize a trim function by replacing it with an equivalent substring
1303 involving a call to len_trim. This only works for expressions where
1304 variables are trimmed. Return true if anything was modified. */
1307 optimize_trim (gfc_expr
*e
)
1312 gfc_ref
**rr
= NULL
;
1314 /* Don't do this optimization within an argument list, because
1315 otherwise aliasing issues may occur. */
1317 if (count_arglist
!= 1)
1320 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_FUNCTION
1321 || e
->value
.function
.isym
== NULL
1322 || e
->value
.function
.isym
->id
!= GFC_ISYM_TRIM
)
1325 a
= e
->value
.function
.actual
->expr
;
1327 if (a
->expr_type
!= EXPR_VARIABLE
)
1330 /* Follow all references to find the correct place to put the newly
1331 created reference. FIXME: Also handle substring references and
1332 array references. Array references cause strange regressions at
1337 for (rr
= &(a
->ref
); *rr
; rr
= &((*rr
)->next
))
1339 if ((*rr
)->type
== REF_SUBSTRING
|| (*rr
)->type
== REF_ARRAY
)
1344 strip_function_call (e
);
1349 /* Create the reference. */
1351 ref
= gfc_get_ref ();
1352 ref
->type
= REF_SUBSTRING
;
1354 /* Set the start of the reference. */
1356 ref
->u
.ss
.start
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 1);
1358 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
1360 fcn
= get_len_trim_call (gfc_copy_expr (e
), gfc_default_integer_kind
);
1362 /* Set the end of the reference to the call to len_trim. */
1364 ref
->u
.ss
.end
= fcn
;
1365 gcc_assert (rr
!= NULL
&& *rr
== NULL
);
1370 /* Optimize minloc(b), where b is rank 1 array, into
1371 (/ minloc(b, dim=1) /), and similarly for maxloc,
1372 as the latter forms are expanded inline. */
1375 optimize_minmaxloc (gfc_expr
**e
)
1378 gfc_actual_arglist
*a
;
1382 || fn
->value
.function
.actual
== NULL
1383 || fn
->value
.function
.actual
->expr
== NULL
1384 || fn
->value
.function
.actual
->expr
->rank
!= 1)
1387 *e
= gfc_get_array_expr (fn
->ts
.type
, fn
->ts
.kind
, &fn
->where
);
1388 (*e
)->shape
= fn
->shape
;
1391 gfc_constructor_append_expr (&(*e
)->value
.constructor
, fn
, &fn
->where
);
1393 name
= XALLOCAVEC (char, strlen (fn
->value
.function
.name
) + 1);
1394 strcpy (name
, fn
->value
.function
.name
);
1395 p
= strstr (name
, "loc0");
1397 fn
->value
.function
.name
= gfc_get_string (name
);
1398 if (fn
->value
.function
.actual
->next
)
1400 a
= fn
->value
.function
.actual
->next
;
1401 gcc_assert (a
->expr
== NULL
);
1405 a
= gfc_get_actual_arglist ();
1406 fn
->value
.function
.actual
->next
= a
;
1408 a
->expr
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
1410 mpz_set_ui (a
->expr
->value
.integer
, 1);
1413 /* Callback function for code checking that we do not pass a DO variable to an
1414 INTENT(OUT) or INTENT(INOUT) dummy variable. */
1417 doloop_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1418 void *data ATTRIBUTE_UNUSED
)
1422 gfc_formal_arglist
*f
;
1423 gfc_actual_arglist
*a
;
1431 /* Grow the temporary storage if necessary. */
1432 if (doloop_level
>= doloop_size
)
1434 doloop_size
= 2 * doloop_size
;
1435 doloop_list
= XRESIZEVEC (gfc_code
*, doloop_list
, doloop_size
);
1438 /* Mark the DO loop variable if there is one. */
1439 if (co
->ext
.iterator
&& co
->ext
.iterator
->var
)
1440 doloop_list
[doloop_level
] = co
;
1442 doloop_list
[doloop_level
] = NULL
;
1447 if (co
->resolved_sym
== NULL
)
1450 f
= gfc_sym_get_dummy_args (co
->resolved_sym
);
1452 /* Withot a formal arglist, there is only unknown INTENT,
1453 which we don't check for. */
1461 for (i
=0; i
<doloop_level
; i
++)
1465 if (doloop_list
[i
] == NULL
)
1468 do_sym
= doloop_list
[i
]->ext
.iterator
->var
->symtree
->n
.sym
;
1470 if (a
->expr
&& a
->expr
->symtree
1471 && a
->expr
->symtree
->n
.sym
== do_sym
)
1473 if (f
->sym
->attr
.intent
== INTENT_OUT
)
1474 gfc_error_now("Variable '%s' at %L set to undefined value "
1475 "inside loop beginning at %L as INTENT(OUT) "
1476 "argument to subroutine '%s'", do_sym
->name
,
1477 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1478 co
->symtree
->n
.sym
->name
);
1479 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
1480 gfc_error_now("Variable '%s' at %L not definable inside loop "
1481 "beginning at %L as INTENT(INOUT) argument to "
1482 "subroutine '%s'", do_sym
->name
,
1483 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1484 co
->symtree
->n
.sym
->name
);
1498 /* Callback function for functions checking that we do not pass a DO variable
1499 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
1502 do_function (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1503 void *data ATTRIBUTE_UNUSED
)
1505 gfc_formal_arglist
*f
;
1506 gfc_actual_arglist
*a
;
1511 if (expr
->expr_type
!= EXPR_FUNCTION
)
1514 /* Intrinsic functions don't modify their arguments. */
1516 if (expr
->value
.function
.isym
)
1519 f
= gfc_sym_get_dummy_args (expr
->symtree
->n
.sym
);
1521 /* Without a formal arglist, there is only unknown INTENT,
1522 which we don't check for. */
1526 a
= expr
->value
.function
.actual
;
1530 for (i
=0; i
<doloop_level
; i
++)
1535 if (doloop_list
[i
] == NULL
)
1538 do_sym
= doloop_list
[i
]->ext
.iterator
->var
->symtree
->n
.sym
;
1540 if (a
->expr
&& a
->expr
->symtree
1541 && a
->expr
->symtree
->n
.sym
== do_sym
)
1543 if (f
->sym
->attr
.intent
== INTENT_OUT
)
1544 gfc_error_now("Variable '%s' at %L set to undefined value "
1545 "inside loop beginning at %L as INTENT(OUT) "
1546 "argument to function '%s'", do_sym
->name
,
1547 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1548 expr
->symtree
->n
.sym
->name
);
1549 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
1550 gfc_error_now("Variable '%s' at %L not definable inside loop "
1551 "beginning at %L as INTENT(INOUT) argument to "
1552 "function '%s'", do_sym
->name
,
1553 &a
->expr
->where
, &doloop_list
[i
]->loc
,
1554 expr
->symtree
->n
.sym
->name
);
1565 doloop_warn (gfc_namespace
*ns
)
1567 gfc_code_walker (&ns
->code
, doloop_code
, do_function
, NULL
);
1571 #define WALK_SUBEXPR(NODE) \
1574 result = gfc_expr_walker (&(NODE), exprfn, data); \
1579 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
1581 /* Walk expression *E, calling EXPRFN on each expression in it. */
1584 gfc_expr_walker (gfc_expr
**e
, walk_expr_fn_t exprfn
, void *data
)
1588 int walk_subtrees
= 1;
1589 gfc_actual_arglist
*a
;
1593 int result
= exprfn (e
, &walk_subtrees
, data
);
1597 switch ((*e
)->expr_type
)
1600 WALK_SUBEXPR ((*e
)->value
.op
.op1
);
1601 WALK_SUBEXPR_TAIL ((*e
)->value
.op
.op2
);
1604 for (a
= (*e
)->value
.function
.actual
; a
; a
= a
->next
)
1605 WALK_SUBEXPR (a
->expr
);
1609 WALK_SUBEXPR ((*e
)->value
.compcall
.base_object
);
1610 for (a
= (*e
)->value
.compcall
.actual
; a
; a
= a
->next
)
1611 WALK_SUBEXPR (a
->expr
);
1614 case EXPR_STRUCTURE
:
1616 for (c
= gfc_constructor_first ((*e
)->value
.constructor
); c
;
1617 c
= gfc_constructor_next (c
))
1619 if (c
->iterator
== NULL
)
1620 WALK_SUBEXPR (c
->expr
);
1624 WALK_SUBEXPR (c
->expr
);
1626 WALK_SUBEXPR (c
->iterator
->var
);
1627 WALK_SUBEXPR (c
->iterator
->start
);
1628 WALK_SUBEXPR (c
->iterator
->end
);
1629 WALK_SUBEXPR (c
->iterator
->step
);
1633 if ((*e
)->expr_type
!= EXPR_ARRAY
)
1636 /* Fall through to the variable case in order to walk the
1639 case EXPR_SUBSTRING
:
1641 for (r
= (*e
)->ref
; r
; r
= r
->next
)
1650 if (ar
->type
== AR_SECTION
|| ar
->type
== AR_ELEMENT
)
1652 for (i
=0; i
< ar
->dimen
; i
++)
1654 WALK_SUBEXPR (ar
->start
[i
]);
1655 WALK_SUBEXPR (ar
->end
[i
]);
1656 WALK_SUBEXPR (ar
->stride
[i
]);
1663 WALK_SUBEXPR (r
->u
.ss
.start
);
1664 WALK_SUBEXPR (r
->u
.ss
.end
);
1680 #define WALK_SUBCODE(NODE) \
1683 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
1689 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
1690 on each expression in it. If any of the hooks returns non-zero, that
1691 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
1692 no subcodes or subexpressions are traversed. */
1695 gfc_code_walker (gfc_code
**c
, walk_code_fn_t codefn
, walk_expr_fn_t exprfn
,
1698 for (; *c
; c
= &(*c
)->next
)
1700 int walk_subtrees
= 1;
1701 int result
= codefn (c
, &walk_subtrees
, data
);
1708 gfc_actual_arglist
*a
;
1710 gfc_association_list
*alist
;
1711 bool saved_in_omp_workshare
;
1713 /* There might be statement insertions before the current code,
1714 which must not affect the expression walker. */
1717 saved_in_omp_workshare
= in_omp_workshare
;
1723 WALK_SUBCODE (co
->ext
.block
.ns
->code
);
1724 for (alist
= co
->ext
.block
.assoc
; alist
; alist
= alist
->next
)
1725 WALK_SUBEXPR (alist
->target
);
1730 WALK_SUBEXPR (co
->ext
.iterator
->var
);
1731 WALK_SUBEXPR (co
->ext
.iterator
->start
);
1732 WALK_SUBEXPR (co
->ext
.iterator
->end
);
1733 WALK_SUBEXPR (co
->ext
.iterator
->step
);
1737 case EXEC_ASSIGN_CALL
:
1738 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
1739 WALK_SUBEXPR (a
->expr
);
1743 WALK_SUBEXPR (co
->expr1
);
1744 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
1745 WALK_SUBEXPR (a
->expr
);
1749 WALK_SUBEXPR (co
->expr1
);
1750 for (b
= co
->block
; b
; b
= b
->block
)
1753 for (cp
= b
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
1755 WALK_SUBEXPR (cp
->low
);
1756 WALK_SUBEXPR (cp
->high
);
1758 WALK_SUBCODE (b
->next
);
1763 case EXEC_DEALLOCATE
:
1766 for (a
= co
->ext
.alloc
.list
; a
; a
= a
->next
)
1767 WALK_SUBEXPR (a
->expr
);
1772 case EXEC_DO_CONCURRENT
:
1774 gfc_forall_iterator
*fa
;
1775 for (fa
= co
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
1777 WALK_SUBEXPR (fa
->var
);
1778 WALK_SUBEXPR (fa
->start
);
1779 WALK_SUBEXPR (fa
->end
);
1780 WALK_SUBEXPR (fa
->stride
);
1782 if (co
->op
== EXEC_FORALL
)
1788 WALK_SUBEXPR (co
->ext
.open
->unit
);
1789 WALK_SUBEXPR (co
->ext
.open
->file
);
1790 WALK_SUBEXPR (co
->ext
.open
->status
);
1791 WALK_SUBEXPR (co
->ext
.open
->access
);
1792 WALK_SUBEXPR (co
->ext
.open
->form
);
1793 WALK_SUBEXPR (co
->ext
.open
->recl
);
1794 WALK_SUBEXPR (co
->ext
.open
->blank
);
1795 WALK_SUBEXPR (co
->ext
.open
->position
);
1796 WALK_SUBEXPR (co
->ext
.open
->action
);
1797 WALK_SUBEXPR (co
->ext
.open
->delim
);
1798 WALK_SUBEXPR (co
->ext
.open
->pad
);
1799 WALK_SUBEXPR (co
->ext
.open
->iostat
);
1800 WALK_SUBEXPR (co
->ext
.open
->iomsg
);
1801 WALK_SUBEXPR (co
->ext
.open
->convert
);
1802 WALK_SUBEXPR (co
->ext
.open
->decimal
);
1803 WALK_SUBEXPR (co
->ext
.open
->encoding
);
1804 WALK_SUBEXPR (co
->ext
.open
->round
);
1805 WALK_SUBEXPR (co
->ext
.open
->sign
);
1806 WALK_SUBEXPR (co
->ext
.open
->asynchronous
);
1807 WALK_SUBEXPR (co
->ext
.open
->id
);
1808 WALK_SUBEXPR (co
->ext
.open
->newunit
);
1812 WALK_SUBEXPR (co
->ext
.close
->unit
);
1813 WALK_SUBEXPR (co
->ext
.close
->status
);
1814 WALK_SUBEXPR (co
->ext
.close
->iostat
);
1815 WALK_SUBEXPR (co
->ext
.close
->iomsg
);
1818 case EXEC_BACKSPACE
:
1822 WALK_SUBEXPR (co
->ext
.filepos
->unit
);
1823 WALK_SUBEXPR (co
->ext
.filepos
->iostat
);
1824 WALK_SUBEXPR (co
->ext
.filepos
->iomsg
);
1828 WALK_SUBEXPR (co
->ext
.inquire
->unit
);
1829 WALK_SUBEXPR (co
->ext
.inquire
->file
);
1830 WALK_SUBEXPR (co
->ext
.inquire
->iomsg
);
1831 WALK_SUBEXPR (co
->ext
.inquire
->iostat
);
1832 WALK_SUBEXPR (co
->ext
.inquire
->exist
);
1833 WALK_SUBEXPR (co
->ext
.inquire
->opened
);
1834 WALK_SUBEXPR (co
->ext
.inquire
->number
);
1835 WALK_SUBEXPR (co
->ext
.inquire
->named
);
1836 WALK_SUBEXPR (co
->ext
.inquire
->name
);
1837 WALK_SUBEXPR (co
->ext
.inquire
->access
);
1838 WALK_SUBEXPR (co
->ext
.inquire
->sequential
);
1839 WALK_SUBEXPR (co
->ext
.inquire
->direct
);
1840 WALK_SUBEXPR (co
->ext
.inquire
->form
);
1841 WALK_SUBEXPR (co
->ext
.inquire
->formatted
);
1842 WALK_SUBEXPR (co
->ext
.inquire
->unformatted
);
1843 WALK_SUBEXPR (co
->ext
.inquire
->recl
);
1844 WALK_SUBEXPR (co
->ext
.inquire
->nextrec
);
1845 WALK_SUBEXPR (co
->ext
.inquire
->blank
);
1846 WALK_SUBEXPR (co
->ext
.inquire
->position
);
1847 WALK_SUBEXPR (co
->ext
.inquire
->action
);
1848 WALK_SUBEXPR (co
->ext
.inquire
->read
);
1849 WALK_SUBEXPR (co
->ext
.inquire
->write
);
1850 WALK_SUBEXPR (co
->ext
.inquire
->readwrite
);
1851 WALK_SUBEXPR (co
->ext
.inquire
->delim
);
1852 WALK_SUBEXPR (co
->ext
.inquire
->encoding
);
1853 WALK_SUBEXPR (co
->ext
.inquire
->pad
);
1854 WALK_SUBEXPR (co
->ext
.inquire
->iolength
);
1855 WALK_SUBEXPR (co
->ext
.inquire
->convert
);
1856 WALK_SUBEXPR (co
->ext
.inquire
->strm_pos
);
1857 WALK_SUBEXPR (co
->ext
.inquire
->asynchronous
);
1858 WALK_SUBEXPR (co
->ext
.inquire
->decimal
);
1859 WALK_SUBEXPR (co
->ext
.inquire
->pending
);
1860 WALK_SUBEXPR (co
->ext
.inquire
->id
);
1861 WALK_SUBEXPR (co
->ext
.inquire
->sign
);
1862 WALK_SUBEXPR (co
->ext
.inquire
->size
);
1863 WALK_SUBEXPR (co
->ext
.inquire
->round
);
1867 WALK_SUBEXPR (co
->ext
.wait
->unit
);
1868 WALK_SUBEXPR (co
->ext
.wait
->iostat
);
1869 WALK_SUBEXPR (co
->ext
.wait
->iomsg
);
1870 WALK_SUBEXPR (co
->ext
.wait
->id
);
1875 WALK_SUBEXPR (co
->ext
.dt
->io_unit
);
1876 WALK_SUBEXPR (co
->ext
.dt
->format_expr
);
1877 WALK_SUBEXPR (co
->ext
.dt
->rec
);
1878 WALK_SUBEXPR (co
->ext
.dt
->advance
);
1879 WALK_SUBEXPR (co
->ext
.dt
->iostat
);
1880 WALK_SUBEXPR (co
->ext
.dt
->size
);
1881 WALK_SUBEXPR (co
->ext
.dt
->iomsg
);
1882 WALK_SUBEXPR (co
->ext
.dt
->id
);
1883 WALK_SUBEXPR (co
->ext
.dt
->pos
);
1884 WALK_SUBEXPR (co
->ext
.dt
->asynchronous
);
1885 WALK_SUBEXPR (co
->ext
.dt
->blank
);
1886 WALK_SUBEXPR (co
->ext
.dt
->decimal
);
1887 WALK_SUBEXPR (co
->ext
.dt
->delim
);
1888 WALK_SUBEXPR (co
->ext
.dt
->pad
);
1889 WALK_SUBEXPR (co
->ext
.dt
->round
);
1890 WALK_SUBEXPR (co
->ext
.dt
->sign
);
1891 WALK_SUBEXPR (co
->ext
.dt
->extra_comma
);
1894 case EXEC_OMP_PARALLEL
:
1895 case EXEC_OMP_PARALLEL_DO
:
1896 case EXEC_OMP_PARALLEL_SECTIONS
:
1898 in_omp_workshare
= false;
1900 /* This goto serves as a shortcut to avoid code
1901 duplication or a larger if or switch statement. */
1902 goto check_omp_clauses
;
1904 case EXEC_OMP_WORKSHARE
:
1905 case EXEC_OMP_PARALLEL_WORKSHARE
:
1907 in_omp_workshare
= true;
1912 case EXEC_OMP_SECTIONS
:
1913 case EXEC_OMP_SINGLE
:
1914 case EXEC_OMP_END_SINGLE
:
1917 /* Come to this label only from the
1918 EXEC_OMP_PARALLEL_* cases above. */
1922 if (co
->ext
.omp_clauses
)
1924 WALK_SUBEXPR (co
->ext
.omp_clauses
->if_expr
);
1925 WALK_SUBEXPR (co
->ext
.omp_clauses
->final_expr
);
1926 WALK_SUBEXPR (co
->ext
.omp_clauses
->num_threads
);
1927 WALK_SUBEXPR (co
->ext
.omp_clauses
->chunk_size
);
1934 WALK_SUBEXPR (co
->expr1
);
1935 WALK_SUBEXPR (co
->expr2
);
1936 WALK_SUBEXPR (co
->expr3
);
1937 WALK_SUBEXPR (co
->expr4
);
1938 for (b
= co
->block
; b
; b
= b
->block
)
1940 WALK_SUBEXPR (b
->expr1
);
1941 WALK_SUBEXPR (b
->expr2
);
1942 WALK_SUBCODE (b
->next
);
1945 if (co
->op
== EXEC_FORALL
)
1948 if (co
->op
== EXEC_DO
)
1951 in_omp_workshare
= saved_in_omp_workshare
;