1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010 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/>. */
26 #include "dependency.h"
27 #include "constructor.h"
30 /* Forward declarations. */
32 static void strip_function_call (gfc_expr
*);
33 static void optimize_namespace (gfc_namespace
*);
34 static void optimize_assignment (gfc_code
*);
35 static bool optimize_op (gfc_expr
*);
36 static bool optimize_comparison (gfc_expr
*, gfc_intrinsic_op
);
37 static bool optimize_trim (gfc_expr
*);
39 /* How deep we are inside an argument list. */
41 static int count_arglist
;
43 /* Pointer to an array of gfc_expr ** we operate on, plus its size
46 static gfc_expr
***expr_array
;
47 static int expr_size
, expr_count
;
49 /* Pointer to the gfc_code we currently work on - to be able to insert
50 a statement before. */
52 static gfc_code
**current_code
;
54 /* The namespace we are currently dealing with. */
56 gfc_namespace
*current_ns
;
58 /* Entry point - run all passes for a namespace. So far, only an
59 optimization pass is run. */
62 gfc_run_passes (gfc_namespace
*ns
)
67 expr_array
= XNEWVEC(gfc_expr
**, expr_size
);
69 optimize_namespace (ns
);
70 if (gfc_option
.dump_fortran_optimized
)
71 gfc_dump_parse_tree (ns
, stdout
);
73 /* FIXME: The following should be XDELETEVEC(expr_array);
74 but we cannot do that because it depends on free. */
75 gfc_free (expr_array
);
79 /* Callback for each gfc_code node invoked through gfc_code_walker
80 from optimize_namespace. */
83 optimize_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
84 void *data ATTRIBUTE_UNUSED
)
91 if (op
== EXEC_CALL
|| op
== EXEC_COMPCALL
|| op
== EXEC_ASSIGN_CALL
92 || op
== EXEC_CALL_PPC
)
97 if (op
== EXEC_ASSIGN
)
98 optimize_assignment (*c
);
102 /* Callback for each gfc_expr node invoked through gfc_code_walker
103 from optimize_namespace. */
106 optimize_expr (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
107 void *data ATTRIBUTE_UNUSED
)
111 if ((*e
)->expr_type
== EXPR_FUNCTION
)
114 function_expr
= true;
117 function_expr
= false;
119 if (optimize_trim (*e
))
120 gfc_simplify_expr (*e
, 0);
122 if ((*e
)->expr_type
== EXPR_OP
&& optimize_op (*e
))
123 gfc_simplify_expr (*e
, 0);
132 /* Callback function for common function elimination, called from cfe_expr_0.
133 Put all eligible function expressions into expr_array. We can't do
134 allocatable functions. */
137 cfe_register_funcs (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
138 void *data ATTRIBUTE_UNUSED
)
141 /* FIXME - there is a bug in the insertion code for DO loops. Bail
144 if ((*current_code
)->op
== EXEC_DO
)
147 if ((*e
)->expr_type
!= EXPR_FUNCTION
)
150 /* We don't do character functions (yet). */
151 if ((*e
)->ts
.type
== BT_CHARACTER
)
154 /* If we don't know the shape at compile time, we do not create a temporary
155 variable to hold the intermediate result. FIXME: Change this later when
156 allocation on assignment works for intrinsics. */
158 if ((*e
)->rank
> 0 && (*e
)->shape
== NULL
)
161 /* Skip the test for pure functions if -faggressive-function-elimination
163 if ((*e
)->value
.function
.esym
)
165 if ((*e
)->value
.function
.esym
->attr
.allocatable
)
168 /* Don't create an array temporary for elemental functions. */
169 if ((*e
)->value
.function
.esym
->attr
.elemental
&& (*e
)->rank
> 0)
172 /* Only eliminate potentially impure functions if the
173 user specifically requested it. */
174 if (!gfc_option
.flag_aggressive_function_elimination
175 && !(*e
)->value
.function
.esym
->attr
.pure
176 && !(*e
)->value
.function
.esym
->attr
.implicit_pure
)
180 if ((*e
)->value
.function
.isym
)
182 /* Conversions are handled on the fly by the middle end,
183 transpose during trans-* stages. */
184 if ((*e
)->value
.function
.isym
->id
== GFC_ISYM_CONVERSION
185 || (*e
)->value
.function
.isym
->id
== GFC_ISYM_TRANSPOSE
)
188 /* Don't create an array temporary for elemental functions,
189 as this would be wasteful of memory.
190 FIXME: Create a scalar temporary during scalarization. */
191 if ((*e
)->value
.function
.isym
->elemental
&& (*e
)->rank
> 0)
194 if (!(*e
)->value
.function
.isym
->pure
)
198 if (expr_count
>= expr_size
)
200 expr_size
+= expr_size
;
201 expr_array
= XRESIZEVEC(gfc_expr
**, expr_array
, expr_size
);
203 expr_array
[expr_count
] = e
;
208 /* Returns a new expression (a variable) to be used in place of the old one,
209 with an an assignment statement before the current statement to set
210 the value of the variable. */
213 create_var (gfc_expr
* e
)
215 char name
[GFC_MAX_SYMBOL_LEN
+1];
217 gfc_symtree
*symtree
;
223 sprintf(name
, "__var_%d",num
++);
224 if (gfc_get_sym_tree (name
, current_ns
, &symtree
, false) != 0)
227 symbol
= symtree
->n
.sym
;
229 symbol
->as
= gfc_get_array_spec ();
230 symbol
->as
->rank
= e
->rank
;
231 symbol
->as
->type
= AS_EXPLICIT
;
232 for (i
=0; i
<e
->rank
; i
++)
236 p
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
238 mpz_set_si (p
->value
.integer
, 1);
239 symbol
->as
->lower
[i
] = p
;
241 q
= gfc_get_constant_expr (BT_INTEGER
, gfc_index_integer_kind
,
243 mpz_set (q
->value
.integer
, e
->shape
[i
]);
244 symbol
->as
->upper
[i
] = q
;
247 symbol
->attr
.flavor
= FL_VARIABLE
;
248 symbol
->attr
.referenced
= 1;
249 symbol
->attr
.dimension
= e
->rank
> 0;
250 gfc_commit_symbol (symbol
);
252 result
= gfc_get_expr ();
253 result
->expr_type
= EXPR_VARIABLE
;
255 result
->rank
= e
->rank
;
256 result
->shape
= gfc_copy_shape (e
->shape
, e
->rank
);
257 result
->symtree
= symtree
;
258 result
->where
= e
->where
;
261 result
->ref
= gfc_get_ref ();
262 result
->ref
->type
= REF_ARRAY
;
263 result
->ref
->u
.ar
.type
= AR_FULL
;
264 result
->ref
->u
.ar
.where
= e
->where
;
265 result
->ref
->u
.ar
.as
= symbol
->as
;
266 if (gfc_option
.warn_array_temp
)
267 gfc_warning ("Creating array temporary at %L", &(e
->where
));
270 /* Generate the new assignment. */
271 n
= XCNEW (gfc_code
);
273 n
->loc
= (*current_code
)->loc
;
274 n
->next
= *current_code
;
275 n
->expr1
= gfc_copy_expr (result
);
282 /* Callback function for the code walker for doing common function
283 elimination. This builds up the list of functions in the expression
284 and goes through them to detect duplicates, which it then replaces
288 cfe_expr_0 (gfc_expr
**e
, int *walk_subtrees
,
289 void *data ATTRIBUTE_UNUSED
)
296 gfc_expr_walker (e
, cfe_register_funcs
, NULL
);
298 /* Walk backwards through all the functions to make sure we
299 catch the leaf functions first. */
300 for (i
=expr_count
-1; i
>=1; i
--)
302 /* Skip if the function has been replaced by a variable already. */
303 if ((*(expr_array
[i
]))->expr_type
== EXPR_VARIABLE
)
307 for (j
=i
-1; j
>=0; j
--)
309 if (gfc_dep_compare_functions(*(expr_array
[i
]),
310 *(expr_array
[j
]), true) == 0)
313 newvar
= create_var (*(expr_array
[i
]));
314 gfc_free (*(expr_array
[j
]));
315 *(expr_array
[j
]) = gfc_copy_expr (newvar
);
319 *(expr_array
[i
]) = newvar
;
322 /* We did all the necessary walking in this function. */
327 /* Callback function for common function elimination, called from
328 gfc_code_walker. This keeps track of the current code, in order
329 to insert statements as needed. */
332 cfe_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
333 void *data ATTRIBUTE_UNUSED
)
339 /* Optimize a namespace, including all contained namespaces. */
342 optimize_namespace (gfc_namespace
*ns
)
347 gfc_code_walker (&ns
->code
, cfe_code
, cfe_expr_0
, NULL
);
348 gfc_code_walker (&ns
->code
, optimize_code
, optimize_expr
, NULL
);
350 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
351 optimize_namespace (ns
);
357 a = matmul(b,c) ; a = a + d
358 where the array function is not elemental and not allocatable
359 and does not depend on the left-hand side.
363 optimize_binop_array_assignment (gfc_code
*c
, gfc_expr
**rhs
, bool seen_op
)
368 if (e
->expr_type
== EXPR_OP
)
370 switch (e
->value
.op
.op
)
372 /* Unary operators and exponentiation: Only look at a single
375 case INTRINSIC_UPLUS
:
376 case INTRINSIC_UMINUS
:
377 case INTRINSIC_PARENTHESES
:
378 case INTRINSIC_POWER
:
379 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, seen_op
))
384 /* Binary operators. */
385 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, true))
388 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op2
, true))
394 else if (seen_op
&& e
->expr_type
== EXPR_FUNCTION
&& e
->rank
> 0
395 && ! (e
->value
.function
.esym
396 && (e
->value
.function
.esym
->attr
.elemental
397 || e
->value
.function
.esym
->attr
.allocatable
398 || e
->value
.function
.esym
->ts
.type
!= c
->expr1
->ts
.type
399 || e
->value
.function
.esym
->ts
.kind
!= c
->expr1
->ts
.kind
))
400 && ! (e
->value
.function
.isym
401 && (e
->value
.function
.isym
->elemental
402 || e
->ts
.type
!= c
->expr1
->ts
.type
403 || e
->ts
.kind
!= c
->expr1
->ts
.kind
)))
409 /* Insert a new assignment statement after the current one. */
410 n
= XCNEW (gfc_code
);
416 n
->expr1
= gfc_copy_expr (c
->expr1
);
418 new_expr
= gfc_copy_expr (c
->expr1
);
426 /* Nothing to optimize. */
430 /* Optimizations for an assignment. */
433 optimize_assignment (gfc_code
* c
)
440 /* Optimize away a = trim(b), where a is a character variable. */
442 if (lhs
->ts
.type
== BT_CHARACTER
)
444 if (rhs
->expr_type
== EXPR_FUNCTION
&&
445 rhs
->value
.function
.isym
&&
446 rhs
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
448 strip_function_call (rhs
);
449 optimize_assignment (c
);
454 if (lhs
->rank
> 0 && gfc_check_dependency (lhs
, rhs
, true) == 0)
455 optimize_binop_array_assignment (c
, &rhs
, false);
459 /* Remove an unneeded function call, modifying the expression.
460 This replaces the function call with the value of its
461 first argument. The rest of the argument list is freed. */
464 strip_function_call (gfc_expr
*e
)
467 gfc_actual_arglist
*a
;
469 a
= e
->value
.function
.actual
;
471 /* We should have at least one argument. */
472 gcc_assert (a
->expr
!= NULL
);
476 /* Free the remaining arglist, if any. */
478 gfc_free_actual_arglist (a
->next
);
480 /* Graft the argument expression onto the original function. */
486 /* Recursive optimization of operators. */
489 optimize_op (gfc_expr
*e
)
491 gfc_intrinsic_op op
= e
->value
.op
.op
;
496 case INTRINSIC_EQ_OS
:
498 case INTRINSIC_GE_OS
:
500 case INTRINSIC_LE_OS
:
502 case INTRINSIC_NE_OS
:
504 case INTRINSIC_GT_OS
:
506 case INTRINSIC_LT_OS
:
507 return optimize_comparison (e
, op
);
516 /* Optimize expressions for equality. */
519 optimize_comparison (gfc_expr
*e
, gfc_intrinsic_op op
)
526 op1
= e
->value
.op
.op1
;
527 op2
= e
->value
.op
.op2
;
529 /* Strip off unneeded TRIM calls from string comparisons. */
533 if (op1
->expr_type
== EXPR_FUNCTION
534 && op1
->value
.function
.isym
535 && op1
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
537 strip_function_call (op1
);
541 if (op2
->expr_type
== EXPR_FUNCTION
542 && op2
->value
.function
.isym
543 && op2
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
545 strip_function_call (op2
);
551 optimize_comparison (e
, op
);
555 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
556 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
557 handles them well). However, there are also cases that need a non-scalar
558 argument. For example the any intrinsic. See PR 45380. */
562 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
564 if (flag_finite_math_only
565 || (op1
->ts
.type
!= BT_REAL
&& op2
->ts
.type
!= BT_REAL
566 && op1
->ts
.type
!= BT_COMPLEX
&& op2
->ts
.type
!= BT_COMPLEX
))
568 eq
= gfc_dep_compare_expr (op1
, op2
);
571 /* Replace A // B < A // C with B < C, and A // B < C // B
573 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
574 && op1
->value
.op
.op
== INTRINSIC_CONCAT
575 && op2
->value
.op
.op
== INTRINSIC_CONCAT
)
577 gfc_expr
*op1_left
= op1
->value
.op
.op1
;
578 gfc_expr
*op2_left
= op2
->value
.op
.op1
;
579 gfc_expr
*op1_right
= op1
->value
.op
.op2
;
580 gfc_expr
*op2_right
= op2
->value
.op
.op2
;
582 if (gfc_dep_compare_expr (op1_left
, op2_left
) == 0)
584 /* Watch out for 'A ' // x vs. 'A' // x. */
586 if (op1_left
->expr_type
== EXPR_CONSTANT
587 && op2_left
->expr_type
== EXPR_CONSTANT
588 && op1_left
->value
.character
.length
589 != op2_left
->value
.character
.length
)
595 e
->value
.op
.op1
= op1_right
;
596 e
->value
.op
.op2
= op2_right
;
597 optimize_comparison (e
, op
);
601 if (gfc_dep_compare_expr (op1_right
, op2_right
) == 0)
603 gfc_free (op1_right
);
604 gfc_free (op2_right
);
605 e
->value
.op
.op1
= op1_left
;
606 e
->value
.op
.op2
= op2_left
;
607 optimize_comparison (e
, op
);
614 /* eq can only be -1, 0 or 1 at this point. */
618 case INTRINSIC_EQ_OS
:
623 case INTRINSIC_GE_OS
:
628 case INTRINSIC_LE_OS
:
633 case INTRINSIC_NE_OS
:
638 case INTRINSIC_GT_OS
:
643 case INTRINSIC_LT_OS
:
648 gfc_internal_error ("illegal OP in optimize_comparison");
652 /* Replace the expression by a constant expression. The typespec
653 and where remains the way it is. */
656 e
->expr_type
= EXPR_CONSTANT
;
657 e
->value
.logical
= result
;
665 /* Optimize a trim function by replacing it with an equivalent substring
666 involving a call to len_trim. This only works for expressions where
667 variables are trimmed. Return true if anything was modified. */
670 optimize_trim (gfc_expr
*e
)
675 gfc_actual_arglist
*actual_arglist
, *next
;
678 /* Don't do this optimization within an argument list, because
679 otherwise aliasing issues may occur. */
681 if (count_arglist
!= 1)
684 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_FUNCTION
685 || e
->value
.function
.isym
== NULL
686 || e
->value
.function
.isym
->id
!= GFC_ISYM_TRIM
)
689 a
= e
->value
.function
.actual
->expr
;
691 if (a
->expr_type
!= EXPR_VARIABLE
)
694 /* Follow all references to find the correct place to put the newly
695 created reference. FIXME: Also handle substring references and
696 array references. Array references cause strange regressions at
701 for (rr
= &(a
->ref
); *rr
; rr
= &((*rr
)->next
))
703 if ((*rr
)->type
== REF_SUBSTRING
|| (*rr
)->type
== REF_ARRAY
)
708 strip_function_call (e
);
713 /* Create the reference. */
715 ref
= gfc_get_ref ();
716 ref
->type
= REF_SUBSTRING
;
718 /* Set the start of the reference. */
720 ref
->u
.ss
.start
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, 1);
722 /* Build the function call to len_trim(x, gfc_defaul_integer_kind). */
724 fcn
= gfc_get_expr ();
725 fcn
->expr_type
= EXPR_FUNCTION
;
726 fcn
->value
.function
.isym
=
727 gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM
);
728 actual_arglist
= gfc_get_actual_arglist ();
729 actual_arglist
->expr
= gfc_copy_expr (e
);
730 next
= gfc_get_actual_arglist ();
731 next
->expr
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
,
732 gfc_default_integer_kind
);
733 actual_arglist
->next
= next
;
734 fcn
->value
.function
.actual
= actual_arglist
;
736 /* Set the end of the reference to the call to len_trim. */
739 gcc_assert (*rr
== NULL
);
744 #define WALK_SUBEXPR(NODE) \
747 result = gfc_expr_walker (&(NODE), exprfn, data); \
752 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
754 /* Walk expression *E, calling EXPRFN on each expression in it. */
757 gfc_expr_walker (gfc_expr
**e
, walk_expr_fn_t exprfn
, void *data
)
761 int walk_subtrees
= 1;
762 gfc_actual_arglist
*a
;
766 int result
= exprfn (e
, &walk_subtrees
, data
);
770 switch ((*e
)->expr_type
)
773 WALK_SUBEXPR ((*e
)->value
.op
.op1
);
774 WALK_SUBEXPR_TAIL ((*e
)->value
.op
.op2
);
777 for (a
= (*e
)->value
.function
.actual
; a
; a
= a
->next
)
778 WALK_SUBEXPR (a
->expr
);
782 WALK_SUBEXPR ((*e
)->value
.compcall
.base_object
);
783 for (a
= (*e
)->value
.compcall
.actual
; a
; a
= a
->next
)
784 WALK_SUBEXPR (a
->expr
);
789 for (c
= gfc_constructor_first ((*e
)->value
.constructor
); c
;
790 c
= gfc_constructor_next (c
))
792 WALK_SUBEXPR (c
->expr
);
793 if (c
->iterator
!= NULL
)
795 WALK_SUBEXPR (c
->iterator
->var
);
796 WALK_SUBEXPR (c
->iterator
->start
);
797 WALK_SUBEXPR (c
->iterator
->end
);
798 WALK_SUBEXPR (c
->iterator
->step
);
802 if ((*e
)->expr_type
!= EXPR_ARRAY
)
805 /* Fall through to the variable case in order to walk the
810 for (r
= (*e
)->ref
; r
; r
= r
->next
)
819 if (ar
->type
== AR_SECTION
|| ar
->type
== AR_ELEMENT
)
821 for (i
=0; i
< ar
->dimen
; i
++)
823 WALK_SUBEXPR (ar
->start
[i
]);
824 WALK_SUBEXPR (ar
->end
[i
]);
825 WALK_SUBEXPR (ar
->stride
[i
]);
832 WALK_SUBEXPR (r
->u
.ss
.start
);
833 WALK_SUBEXPR (r
->u
.ss
.end
);
849 #define WALK_SUBCODE(NODE) \
852 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
858 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
859 on each expression in it. If any of the hooks returns non-zero, that
860 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
861 no subcodes or subexpressions are traversed. */
864 gfc_code_walker (gfc_code
**c
, walk_code_fn_t codefn
, walk_expr_fn_t exprfn
,
867 for (; *c
; c
= &(*c
)->next
)
869 int walk_subtrees
= 1;
870 int result
= codefn (c
, &walk_subtrees
, data
);
877 gfc_actual_arglist
*a
;
882 WALK_SUBEXPR ((*c
)->ext
.iterator
->var
);
883 WALK_SUBEXPR ((*c
)->ext
.iterator
->start
);
884 WALK_SUBEXPR ((*c
)->ext
.iterator
->end
);
885 WALK_SUBEXPR ((*c
)->ext
.iterator
->step
);
889 case EXEC_ASSIGN_CALL
:
890 for (a
= (*c
)->ext
.actual
; a
; a
= a
->next
)
891 WALK_SUBEXPR (a
->expr
);
895 WALK_SUBEXPR ((*c
)->expr1
);
896 for (a
= (*c
)->ext
.actual
; a
; a
= a
->next
)
897 WALK_SUBEXPR (a
->expr
);
901 WALK_SUBEXPR ((*c
)->expr1
);
902 for (b
= (*c
)->block
; b
; b
= b
->block
)
905 for (cp
= b
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
907 WALK_SUBEXPR (cp
->low
);
908 WALK_SUBEXPR (cp
->high
);
910 WALK_SUBCODE (b
->next
);
915 case EXEC_DEALLOCATE
:
918 for (a
= (*c
)->ext
.alloc
.list
; a
; a
= a
->next
)
919 WALK_SUBEXPR (a
->expr
);
925 gfc_forall_iterator
*fa
;
926 for (fa
= (*c
)->ext
.forall_iterator
; fa
; fa
= fa
->next
)
928 WALK_SUBEXPR (fa
->var
);
929 WALK_SUBEXPR (fa
->start
);
930 WALK_SUBEXPR (fa
->end
);
931 WALK_SUBEXPR (fa
->stride
);
937 WALK_SUBEXPR ((*c
)->ext
.open
->unit
);
938 WALK_SUBEXPR ((*c
)->ext
.open
->file
);
939 WALK_SUBEXPR ((*c
)->ext
.open
->status
);
940 WALK_SUBEXPR ((*c
)->ext
.open
->access
);
941 WALK_SUBEXPR ((*c
)->ext
.open
->form
);
942 WALK_SUBEXPR ((*c
)->ext
.open
->recl
);
943 WALK_SUBEXPR ((*c
)->ext
.open
->blank
);
944 WALK_SUBEXPR ((*c
)->ext
.open
->position
);
945 WALK_SUBEXPR ((*c
)->ext
.open
->action
);
946 WALK_SUBEXPR ((*c
)->ext
.open
->delim
);
947 WALK_SUBEXPR ((*c
)->ext
.open
->pad
);
948 WALK_SUBEXPR ((*c
)->ext
.open
->iostat
);
949 WALK_SUBEXPR ((*c
)->ext
.open
->iomsg
);
950 WALK_SUBEXPR ((*c
)->ext
.open
->convert
);
951 WALK_SUBEXPR ((*c
)->ext
.open
->decimal
);
952 WALK_SUBEXPR ((*c
)->ext
.open
->encoding
);
953 WALK_SUBEXPR ((*c
)->ext
.open
->round
);
954 WALK_SUBEXPR ((*c
)->ext
.open
->sign
);
955 WALK_SUBEXPR ((*c
)->ext
.open
->asynchronous
);
956 WALK_SUBEXPR ((*c
)->ext
.open
->id
);
957 WALK_SUBEXPR ((*c
)->ext
.open
->newunit
);
961 WALK_SUBEXPR ((*c
)->ext
.close
->unit
);
962 WALK_SUBEXPR ((*c
)->ext
.close
->status
);
963 WALK_SUBEXPR ((*c
)->ext
.close
->iostat
);
964 WALK_SUBEXPR ((*c
)->ext
.close
->iomsg
);
971 WALK_SUBEXPR ((*c
)->ext
.filepos
->unit
);
972 WALK_SUBEXPR ((*c
)->ext
.filepos
->iostat
);
973 WALK_SUBEXPR ((*c
)->ext
.filepos
->iomsg
);
977 WALK_SUBEXPR ((*c
)->ext
.inquire
->unit
);
978 WALK_SUBEXPR ((*c
)->ext
.inquire
->file
);
979 WALK_SUBEXPR ((*c
)->ext
.inquire
->iomsg
);
980 WALK_SUBEXPR ((*c
)->ext
.inquire
->iostat
);
981 WALK_SUBEXPR ((*c
)->ext
.inquire
->exist
);
982 WALK_SUBEXPR ((*c
)->ext
.inquire
->opened
);
983 WALK_SUBEXPR ((*c
)->ext
.inquire
->number
);
984 WALK_SUBEXPR ((*c
)->ext
.inquire
->named
);
985 WALK_SUBEXPR ((*c
)->ext
.inquire
->name
);
986 WALK_SUBEXPR ((*c
)->ext
.inquire
->access
);
987 WALK_SUBEXPR ((*c
)->ext
.inquire
->sequential
);
988 WALK_SUBEXPR ((*c
)->ext
.inquire
->direct
);
989 WALK_SUBEXPR ((*c
)->ext
.inquire
->form
);
990 WALK_SUBEXPR ((*c
)->ext
.inquire
->formatted
);
991 WALK_SUBEXPR ((*c
)->ext
.inquire
->unformatted
);
992 WALK_SUBEXPR ((*c
)->ext
.inquire
->recl
);
993 WALK_SUBEXPR ((*c
)->ext
.inquire
->nextrec
);
994 WALK_SUBEXPR ((*c
)->ext
.inquire
->blank
);
995 WALK_SUBEXPR ((*c
)->ext
.inquire
->position
);
996 WALK_SUBEXPR ((*c
)->ext
.inquire
->action
);
997 WALK_SUBEXPR ((*c
)->ext
.inquire
->read
);
998 WALK_SUBEXPR ((*c
)->ext
.inquire
->write
);
999 WALK_SUBEXPR ((*c
)->ext
.inquire
->readwrite
);
1000 WALK_SUBEXPR ((*c
)->ext
.inquire
->delim
);
1001 WALK_SUBEXPR ((*c
)->ext
.inquire
->encoding
);
1002 WALK_SUBEXPR ((*c
)->ext
.inquire
->pad
);
1003 WALK_SUBEXPR ((*c
)->ext
.inquire
->iolength
);
1004 WALK_SUBEXPR ((*c
)->ext
.inquire
->convert
);
1005 WALK_SUBEXPR ((*c
)->ext
.inquire
->strm_pos
);
1006 WALK_SUBEXPR ((*c
)->ext
.inquire
->asynchronous
);
1007 WALK_SUBEXPR ((*c
)->ext
.inquire
->decimal
);
1008 WALK_SUBEXPR ((*c
)->ext
.inquire
->pending
);
1009 WALK_SUBEXPR ((*c
)->ext
.inquire
->id
);
1010 WALK_SUBEXPR ((*c
)->ext
.inquire
->sign
);
1011 WALK_SUBEXPR ((*c
)->ext
.inquire
->size
);
1012 WALK_SUBEXPR ((*c
)->ext
.inquire
->round
);
1016 WALK_SUBEXPR ((*c
)->ext
.wait
->unit
);
1017 WALK_SUBEXPR ((*c
)->ext
.wait
->iostat
);
1018 WALK_SUBEXPR ((*c
)->ext
.wait
->iomsg
);
1019 WALK_SUBEXPR ((*c
)->ext
.wait
->id
);
1024 WALK_SUBEXPR ((*c
)->ext
.dt
->io_unit
);
1025 WALK_SUBEXPR ((*c
)->ext
.dt
->format_expr
);
1026 WALK_SUBEXPR ((*c
)->ext
.dt
->rec
);
1027 WALK_SUBEXPR ((*c
)->ext
.dt
->advance
);
1028 WALK_SUBEXPR ((*c
)->ext
.dt
->iostat
);
1029 WALK_SUBEXPR ((*c
)->ext
.dt
->size
);
1030 WALK_SUBEXPR ((*c
)->ext
.dt
->iomsg
);
1031 WALK_SUBEXPR ((*c
)->ext
.dt
->id
);
1032 WALK_SUBEXPR ((*c
)->ext
.dt
->pos
);
1033 WALK_SUBEXPR ((*c
)->ext
.dt
->asynchronous
);
1034 WALK_SUBEXPR ((*c
)->ext
.dt
->blank
);
1035 WALK_SUBEXPR ((*c
)->ext
.dt
->decimal
);
1036 WALK_SUBEXPR ((*c
)->ext
.dt
->delim
);
1037 WALK_SUBEXPR ((*c
)->ext
.dt
->pad
);
1038 WALK_SUBEXPR ((*c
)->ext
.dt
->round
);
1039 WALK_SUBEXPR ((*c
)->ext
.dt
->sign
);
1040 WALK_SUBEXPR ((*c
)->ext
.dt
->extra_comma
);
1044 case EXEC_OMP_PARALLEL
:
1045 case EXEC_OMP_PARALLEL_DO
:
1046 case EXEC_OMP_PARALLEL_SECTIONS
:
1047 case EXEC_OMP_PARALLEL_WORKSHARE
:
1048 case EXEC_OMP_SECTIONS
:
1049 case EXEC_OMP_SINGLE
:
1050 case EXEC_OMP_WORKSHARE
:
1051 case EXEC_OMP_END_SINGLE
:
1053 if ((*c
)->ext
.omp_clauses
)
1055 WALK_SUBEXPR ((*c
)->ext
.omp_clauses
->if_expr
);
1056 WALK_SUBEXPR ((*c
)->ext
.omp_clauses
->num_threads
);
1057 WALK_SUBEXPR ((*c
)->ext
.omp_clauses
->chunk_size
);
1064 WALK_SUBEXPR ((*c
)->expr1
);
1065 WALK_SUBEXPR ((*c
)->expr2
);
1066 WALK_SUBEXPR ((*c
)->expr3
);
1067 for (b
= (*c
)->block
; b
; b
= b
->block
)
1069 WALK_SUBEXPR (b
->expr1
);
1070 WALK_SUBEXPR (b
->expr2
);
1071 WALK_SUBCODE (b
->next
);