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 *);
38 static bool optimize_lexical_comparison (gfc_expr *);
40 /* How deep we are inside an argument list. */
42 static int count_arglist;
44 /* Pointer to an array of gfc_expr ** we operate on, plus its size
47 static gfc_expr ***expr_array;
48 static int expr_size, expr_count;
50 /* Pointer to the gfc_code we currently work on - to be able to insert
51 a block before the statement. */
53 static gfc_code **current_code;
55 /* Pointer to the block to be inserted, and the statement we are
56 changing within the block. */
58 static gfc_code *inserted_block, **changed_statement;
60 /* The namespace we are currently dealing with. */
62 gfc_namespace *current_ns;
64 /* Entry point - run all passes for a namespace. So far, only an
65 optimization pass is run. */
68 gfc_run_passes (gfc_namespace *ns)
70 if (gfc_option.flag_frontend_optimize)
73 expr_array = XNEWVEC(gfc_expr **, expr_size);
75 optimize_namespace (ns);
76 if (gfc_option.dump_fortran_optimized)
77 gfc_dump_parse_tree (ns, stdout);
79 XDELETEVEC (expr_array);
83 /* Callback for each gfc_code node invoked through gfc_code_walker
84 from optimize_namespace. */
87 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
88 void *data ATTRIBUTE_UNUSED)
95 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
96 || op == EXEC_CALL_PPC)
101 if (op == EXEC_ASSIGN)
102 optimize_assignment (*c);
106 /* Callback for each gfc_expr node invoked through gfc_code_walker
107 from optimize_namespace. */
110 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
111 void *data ATTRIBUTE_UNUSED)
115 if ((*e)->expr_type == EXPR_FUNCTION)
118 function_expr = true;
121 function_expr = false;
123 if (optimize_trim (*e))
124 gfc_simplify_expr (*e, 0);
126 if (optimize_lexical_comparison (*e))
127 gfc_simplify_expr (*e, 0);
129 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
130 gfc_simplify_expr (*e, 0);
139 /* Callback function for common function elimination, called from cfe_expr_0.
140 Put all eligible function expressions into expr_array. */
143 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
144 void *data ATTRIBUTE_UNUSED)
147 if ((*e)->expr_type != EXPR_FUNCTION)
150 /* We don't do character functions with unknown charlens. */
151 if ((*e)->ts.type == BT_CHARACTER
152 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
153 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
156 /* If we don't know the shape at compile time, we create an allocatable
157 temporary variable to hold the intermediate result, but only if
158 allocation on assignment is active. */
160 if ((*e)->rank > 0 && (*e)->shape == NULL && !gfc_option.flag_realloc_lhs)
163 /* Skip the test for pure functions if -faggressive-function-elimination
165 if ((*e)->value.function.esym)
167 /* Don't create an array temporary for elemental functions. */
168 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
171 /* Only eliminate potentially impure functions if the
172 user specifically requested it. */
173 if (!gfc_option.flag_aggressive_function_elimination
174 && !(*e)->value.function.esym->attr.pure
175 && !(*e)->value.function.esym->attr.implicit_pure)
179 if ((*e)->value.function.isym)
181 /* Conversions are handled on the fly by the middle end,
182 transpose during trans-* stages and TRANSFER by the middle end. */
183 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
184 || (*e)->value.function.isym->id == GFC_ISYM_TRANSPOSE
185 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER)
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. Creates a new BLOCK for the statement if
211 that hasn't already been done and puts the statement, plus the
212 newly created variables, in that block. */
215 create_var (gfc_expr * e)
217 char name[GFC_MAX_SYMBOL_LEN +1];
219 gfc_symtree *symtree;
226 /* If the block hasn't already been created, do so. */
227 if (inserted_block == NULL)
229 inserted_block = XCNEW (gfc_code);
230 inserted_block->op = EXEC_BLOCK;
231 inserted_block->loc = (*current_code)->loc;
232 ns = gfc_build_block_ns (current_ns);
233 inserted_block->ext.block.ns = ns;
234 inserted_block->ext.block.assoc = NULL;
236 ns->code = *current_code;
237 inserted_block->next = (*current_code)->next;
238 changed_statement = &(inserted_block->ext.block.ns->code);
239 (*current_code)->next = NULL;
240 /* Insert the BLOCK at the right position. */
241 *current_code = inserted_block;
244 ns = inserted_block->ext.block.ns;
246 sprintf(name, "__var_%d",num++);
247 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
250 symbol = symtree->n.sym;
255 symbol->as = gfc_get_array_spec ();
256 symbol->as->rank = e->rank;
258 if (e->shape == NULL)
260 /* We don't know the shape at compile time, so we use an
262 symbol->as->type = AS_DEFERRED;
263 symbol->attr.allocatable = 1;
267 symbol->as->type = AS_EXPLICIT;
268 /* Copy the shape. */
269 for (i=0; i<e->rank; i++)
273 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
275 mpz_set_si (p->value.integer, 1);
276 symbol->as->lower[i] = p;
278 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
280 mpz_set (q->value.integer, e->shape[i]);
281 symbol->as->upper[i] = q;
286 symbol->attr.flavor = FL_VARIABLE;
287 symbol->attr.referenced = 1;
288 symbol->attr.dimension = e->rank > 0;
289 gfc_commit_symbol (symbol);
291 result = gfc_get_expr ();
292 result->expr_type = EXPR_VARIABLE;
294 result->rank = e->rank;
295 result->shape = gfc_copy_shape (e->shape, e->rank);
296 result->symtree = symtree;
297 result->where = e->where;
300 result->ref = gfc_get_ref ();
301 result->ref->type = REF_ARRAY;
302 result->ref->u.ar.type = AR_FULL;
303 result->ref->u.ar.where = e->where;
304 result->ref->u.ar.as = symbol->as;
305 if (gfc_option.warn_array_temp)
306 gfc_warning ("Creating array temporary at %L", &(e->where));
309 /* Generate the new assignment. */
310 n = XCNEW (gfc_code);
312 n->loc = (*current_code)->loc;
313 n->next = *changed_statement;
314 n->expr1 = gfc_copy_expr (result);
316 *changed_statement = n;
321 /* Warn about function elimination. */
324 warn_function_elimination (gfc_expr *e)
326 if (e->expr_type != EXPR_FUNCTION)
328 if (e->value.function.esym)
329 gfc_warning ("Removing call to function '%s' at %L",
330 e->value.function.esym->name, &(e->where));
331 else if (e->value.function.isym)
332 gfc_warning ("Removing call to function '%s' at %L",
333 e->value.function.isym->name, &(e->where));
335 /* Callback function for the code walker for doing common function
336 elimination. This builds up the list of functions in the expression
337 and goes through them to detect duplicates, which it then replaces
341 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
342 void *data ATTRIBUTE_UNUSED)
349 gfc_expr_walker (e, cfe_register_funcs, NULL);
351 /* Walk through all the functions. */
353 for (i=1; i<expr_count; i++)
355 /* Skip if the function has been replaced by a variable already. */
356 if ((*(expr_array[i]))->expr_type == EXPR_VARIABLE)
362 if (gfc_dep_compare_functions(*(expr_array[i]),
363 *(expr_array[j]), true) == 0)
366 newvar = create_var (*(expr_array[i]));
368 if (gfc_option.warn_function_elimination)
369 warn_function_elimination (*(expr_array[j]));
371 free (*(expr_array[j]));
372 *(expr_array[j]) = gfc_copy_expr (newvar);
376 *(expr_array[i]) = newvar;
379 /* We did all the necessary walking in this function. */
384 /* Callback function for common function elimination, called from
385 gfc_code_walker. This keeps track of the current code, in order
386 to insert statements as needed. */
389 cfe_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
390 void *data ATTRIBUTE_UNUSED)
393 inserted_block = NULL;
394 changed_statement = NULL;
398 /* Optimize a namespace, including all contained namespaces. */
401 optimize_namespace (gfc_namespace *ns)
406 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
407 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
409 for (ns = ns->contained; ns; ns = ns->sibling)
410 optimize_namespace (ns);
416 a = matmul(b,c) ; a = a + d
417 where the array function is not elemental and not allocatable
418 and does not depend on the left-hand side.
422 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
427 if (e->expr_type == EXPR_OP)
429 switch (e->value.op.op)
431 /* Unary operators and exponentiation: Only look at a single
434 case INTRINSIC_UPLUS:
435 case INTRINSIC_UMINUS:
436 case INTRINSIC_PARENTHESES:
437 case INTRINSIC_POWER:
438 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
443 /* Binary operators. */
444 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
447 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
453 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
454 && ! (e->value.function.esym
455 && (e->value.function.esym->attr.elemental
456 || e->value.function.esym->attr.allocatable
457 || e->value.function.esym->ts.type != c->expr1->ts.type
458 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
459 && ! (e->value.function.isym
460 && (e->value.function.isym->elemental
461 || e->ts.type != c->expr1->ts.type
462 || e->ts.kind != c->expr1->ts.kind)))
468 /* Insert a new assignment statement after the current one. */
469 n = XCNEW (gfc_code);
475 n->expr1 = gfc_copy_expr (c->expr1);
477 new_expr = gfc_copy_expr (c->expr1);
485 /* Nothing to optimize. */
489 /* Remove unneeded TRIMs at the end of expressions. */
492 remove_trim (gfc_expr *rhs)
498 /* Check for a // b // trim(c). Looping is probably not
499 necessary because the parser usually generates
500 (// (// a b ) trim(c) ) , but better safe than sorry. */
502 while (rhs->expr_type == EXPR_OP
503 && rhs->value.op.op == INTRINSIC_CONCAT)
504 rhs = rhs->value.op.op2;
506 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
507 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
509 strip_function_call (rhs);
510 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
518 /* Optimizations for an assignment. */
521 optimize_assignment (gfc_code * c)
528 /* Optimize away a = trim(b), where a is a character variable. */
530 if (lhs->ts.type == BT_CHARACTER)
533 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
534 optimize_binop_array_assignment (c, &rhs, false);
538 /* Remove an unneeded function call, modifying the expression.
539 This replaces the function call with the value of its
540 first argument. The rest of the argument list is freed. */
543 strip_function_call (gfc_expr *e)
546 gfc_actual_arglist *a;
548 a = e->value.function.actual;
550 /* We should have at least one argument. */
551 gcc_assert (a->expr != NULL);
555 /* Free the remaining arglist, if any. */
557 gfc_free_actual_arglist (a->next);
559 /* Graft the argument expression onto the original function. */
565 /* Optimization of lexical comparison functions. */
568 optimize_lexical_comparison (gfc_expr *e)
570 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
573 switch (e->value.function.isym->id)
576 return optimize_comparison (e, INTRINSIC_LE);
579 return optimize_comparison (e, INTRINSIC_GE);
582 return optimize_comparison (e, INTRINSIC_GT);
585 return optimize_comparison (e, INTRINSIC_LT);
593 /* Recursive optimization of operators. */
596 optimize_op (gfc_expr *e)
598 gfc_intrinsic_op op = e->value.op.op;
603 case INTRINSIC_EQ_OS:
605 case INTRINSIC_GE_OS:
607 case INTRINSIC_LE_OS:
609 case INTRINSIC_NE_OS:
611 case INTRINSIC_GT_OS:
613 case INTRINSIC_LT_OS:
614 return optimize_comparison (e, op);
623 /* Optimize expressions for equality. */
626 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
632 gfc_actual_arglist *firstarg, *secondarg;
634 if (e->expr_type == EXPR_OP)
638 op1 = e->value.op.op1;
639 op2 = e->value.op.op2;
641 else if (e->expr_type == EXPR_FUNCTION)
643 /* One of the lexical comparision functions. */
644 firstarg = e->value.function.actual;
645 secondarg = firstarg->next;
646 op1 = firstarg->expr;
647 op2 = secondarg->expr;
652 /* Strip off unneeded TRIM calls from string comparisons. */
654 change = remove_trim (op1);
656 if (remove_trim (op2))
659 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
660 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
661 handles them well). However, there are also cases that need a non-scalar
662 argument. For example the any intrinsic. See PR 45380. */
666 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
668 if (flag_finite_math_only
669 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
670 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
672 eq = gfc_dep_compare_expr (op1, op2);
675 /* Replace A // B < A // C with B < C, and A // B < C // B
677 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
678 && op1->value.op.op == INTRINSIC_CONCAT
679 && op2->value.op.op == INTRINSIC_CONCAT)
681 gfc_expr *op1_left = op1->value.op.op1;
682 gfc_expr *op2_left = op2->value.op.op1;
683 gfc_expr *op1_right = op1->value.op.op2;
684 gfc_expr *op2_right = op2->value.op.op2;
686 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
688 /* Watch out for 'A ' // x vs. 'A' // x. */
690 if (op1_left->expr_type == EXPR_CONSTANT
691 && op2_left->expr_type == EXPR_CONSTANT
692 && op1_left->value.character.length
693 != op2_left->value.character.length)
701 firstarg->expr = op1_right;
702 secondarg->expr = op2_right;
706 e->value.op.op1 = op1_right;
707 e->value.op.op2 = op2_right;
709 optimize_comparison (e, op);
713 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
719 firstarg->expr = op1_left;
720 secondarg->expr = op2_left;
724 e->value.op.op1 = op1_left;
725 e->value.op.op2 = op2_left;
728 optimize_comparison (e, op);
735 /* eq can only be -1, 0 or 1 at this point. */
739 case INTRINSIC_EQ_OS:
744 case INTRINSIC_GE_OS:
749 case INTRINSIC_LE_OS:
754 case INTRINSIC_NE_OS:
759 case INTRINSIC_GT_OS:
764 case INTRINSIC_LT_OS:
769 gfc_internal_error ("illegal OP in optimize_comparison");
773 /* Replace the expression by a constant expression. The typespec
774 and where remains the way it is. */
777 e->expr_type = EXPR_CONSTANT;
778 e->value.logical = result;
786 /* Optimize a trim function by replacing it with an equivalent substring
787 involving a call to len_trim. This only works for expressions where
788 variables are trimmed. Return true if anything was modified. */
791 optimize_trim (gfc_expr *e)
796 gfc_actual_arglist *actual_arglist, *next;
799 /* Don't do this optimization within an argument list, because
800 otherwise aliasing issues may occur. */
802 if (count_arglist != 1)
805 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
806 || e->value.function.isym == NULL
807 || e->value.function.isym->id != GFC_ISYM_TRIM)
810 a = e->value.function.actual->expr;
812 if (a->expr_type != EXPR_VARIABLE)
815 /* Follow all references to find the correct place to put the newly
816 created reference. FIXME: Also handle substring references and
817 array references. Array references cause strange regressions at
822 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
824 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
829 strip_function_call (e);
834 /* Create the reference. */
836 ref = gfc_get_ref ();
837 ref->type = REF_SUBSTRING;
839 /* Set the start of the reference. */
841 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
843 /* Build the function call to len_trim(x, gfc_defaul_integer_kind). */
845 fcn = gfc_get_expr ();
846 fcn->expr_type = EXPR_FUNCTION;
847 fcn->value.function.isym =
848 gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
849 actual_arglist = gfc_get_actual_arglist ();
850 actual_arglist->expr = gfc_copy_expr (e);
851 next = gfc_get_actual_arglist ();
852 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
853 gfc_default_integer_kind);
854 actual_arglist->next = next;
855 fcn->value.function.actual = actual_arglist;
857 /* Set the end of the reference to the call to len_trim. */
860 gcc_assert (*rr == NULL);
865 #define WALK_SUBEXPR(NODE) \
868 result = gfc_expr_walker (&(NODE), exprfn, data); \
873 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
875 /* Walk expression *E, calling EXPRFN on each expression in it. */
878 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
882 int walk_subtrees = 1;
883 gfc_actual_arglist *a;
887 int result = exprfn (e, &walk_subtrees, data);
891 switch ((*e)->expr_type)
894 WALK_SUBEXPR ((*e)->value.op.op1);
895 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
898 for (a = (*e)->value.function.actual; a; a = a->next)
899 WALK_SUBEXPR (a->expr);
903 WALK_SUBEXPR ((*e)->value.compcall.base_object);
904 for (a = (*e)->value.compcall.actual; a; a = a->next)
905 WALK_SUBEXPR (a->expr);
910 for (c = gfc_constructor_first ((*e)->value.constructor); c;
911 c = gfc_constructor_next (c))
913 WALK_SUBEXPR (c->expr);
914 if (c->iterator != NULL)
916 WALK_SUBEXPR (c->iterator->var);
917 WALK_SUBEXPR (c->iterator->start);
918 WALK_SUBEXPR (c->iterator->end);
919 WALK_SUBEXPR (c->iterator->step);
923 if ((*e)->expr_type != EXPR_ARRAY)
926 /* Fall through to the variable case in order to walk the
931 for (r = (*e)->ref; r; r = r->next)
940 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
942 for (i=0; i< ar->dimen; i++)
944 WALK_SUBEXPR (ar->start[i]);
945 WALK_SUBEXPR (ar->end[i]);
946 WALK_SUBEXPR (ar->stride[i]);
953 WALK_SUBEXPR (r->u.ss.start);
954 WALK_SUBEXPR (r->u.ss.end);
970 #define WALK_SUBCODE(NODE) \
973 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
979 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
980 on each expression in it. If any of the hooks returns non-zero, that
981 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
982 no subcodes or subexpressions are traversed. */
985 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
988 for (; *c; c = &(*c)->next)
990 int walk_subtrees = 1;
991 int result = codefn (c, &walk_subtrees, data);
998 gfc_actual_arglist *a;
1001 /* There might be statement insertions before the current code,
1002 which must not affect the expression walker. */
1009 WALK_SUBEXPR (co->ext.iterator->var);
1010 WALK_SUBEXPR (co->ext.iterator->start);
1011 WALK_SUBEXPR (co->ext.iterator->end);
1012 WALK_SUBEXPR (co->ext.iterator->step);
1016 case EXEC_ASSIGN_CALL:
1017 for (a = co->ext.actual; a; a = a->next)
1018 WALK_SUBEXPR (a->expr);
1022 WALK_SUBEXPR (co->expr1);
1023 for (a = co->ext.actual; a; a = a->next)
1024 WALK_SUBEXPR (a->expr);
1028 WALK_SUBEXPR (co->expr1);
1029 for (b = co->block; b; b = b->block)
1032 for (cp = b->ext.block.case_list; cp; cp = cp->next)
1034 WALK_SUBEXPR (cp->low);
1035 WALK_SUBEXPR (cp->high);
1037 WALK_SUBCODE (b->next);
1042 case EXEC_DEALLOCATE:
1045 for (a = co->ext.alloc.list; a; a = a->next)
1046 WALK_SUBEXPR (a->expr);
1052 gfc_forall_iterator *fa;
1053 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
1055 WALK_SUBEXPR (fa->var);
1056 WALK_SUBEXPR (fa->start);
1057 WALK_SUBEXPR (fa->end);
1058 WALK_SUBEXPR (fa->stride);
1064 WALK_SUBEXPR (co->ext.open->unit);
1065 WALK_SUBEXPR (co->ext.open->file);
1066 WALK_SUBEXPR (co->ext.open->status);
1067 WALK_SUBEXPR (co->ext.open->access);
1068 WALK_SUBEXPR (co->ext.open->form);
1069 WALK_SUBEXPR (co->ext.open->recl);
1070 WALK_SUBEXPR (co->ext.open->blank);
1071 WALK_SUBEXPR (co->ext.open->position);
1072 WALK_SUBEXPR (co->ext.open->action);
1073 WALK_SUBEXPR (co->ext.open->delim);
1074 WALK_SUBEXPR (co->ext.open->pad);
1075 WALK_SUBEXPR (co->ext.open->iostat);
1076 WALK_SUBEXPR (co->ext.open->iomsg);
1077 WALK_SUBEXPR (co->ext.open->convert);
1078 WALK_SUBEXPR (co->ext.open->decimal);
1079 WALK_SUBEXPR (co->ext.open->encoding);
1080 WALK_SUBEXPR (co->ext.open->round);
1081 WALK_SUBEXPR (co->ext.open->sign);
1082 WALK_SUBEXPR (co->ext.open->asynchronous);
1083 WALK_SUBEXPR (co->ext.open->id);
1084 WALK_SUBEXPR (co->ext.open->newunit);
1088 WALK_SUBEXPR (co->ext.close->unit);
1089 WALK_SUBEXPR (co->ext.close->status);
1090 WALK_SUBEXPR (co->ext.close->iostat);
1091 WALK_SUBEXPR (co->ext.close->iomsg);
1094 case EXEC_BACKSPACE:
1098 WALK_SUBEXPR (co->ext.filepos->unit);
1099 WALK_SUBEXPR (co->ext.filepos->iostat);
1100 WALK_SUBEXPR (co->ext.filepos->iomsg);
1104 WALK_SUBEXPR (co->ext.inquire->unit);
1105 WALK_SUBEXPR (co->ext.inquire->file);
1106 WALK_SUBEXPR (co->ext.inquire->iomsg);
1107 WALK_SUBEXPR (co->ext.inquire->iostat);
1108 WALK_SUBEXPR (co->ext.inquire->exist);
1109 WALK_SUBEXPR (co->ext.inquire->opened);
1110 WALK_SUBEXPR (co->ext.inquire->number);
1111 WALK_SUBEXPR (co->ext.inquire->named);
1112 WALK_SUBEXPR (co->ext.inquire->name);
1113 WALK_SUBEXPR (co->ext.inquire->access);
1114 WALK_SUBEXPR (co->ext.inquire->sequential);
1115 WALK_SUBEXPR (co->ext.inquire->direct);
1116 WALK_SUBEXPR (co->ext.inquire->form);
1117 WALK_SUBEXPR (co->ext.inquire->formatted);
1118 WALK_SUBEXPR (co->ext.inquire->unformatted);
1119 WALK_SUBEXPR (co->ext.inquire->recl);
1120 WALK_SUBEXPR (co->ext.inquire->nextrec);
1121 WALK_SUBEXPR (co->ext.inquire->blank);
1122 WALK_SUBEXPR (co->ext.inquire->position);
1123 WALK_SUBEXPR (co->ext.inquire->action);
1124 WALK_SUBEXPR (co->ext.inquire->read);
1125 WALK_SUBEXPR (co->ext.inquire->write);
1126 WALK_SUBEXPR (co->ext.inquire->readwrite);
1127 WALK_SUBEXPR (co->ext.inquire->delim);
1128 WALK_SUBEXPR (co->ext.inquire->encoding);
1129 WALK_SUBEXPR (co->ext.inquire->pad);
1130 WALK_SUBEXPR (co->ext.inquire->iolength);
1131 WALK_SUBEXPR (co->ext.inquire->convert);
1132 WALK_SUBEXPR (co->ext.inquire->strm_pos);
1133 WALK_SUBEXPR (co->ext.inquire->asynchronous);
1134 WALK_SUBEXPR (co->ext.inquire->decimal);
1135 WALK_SUBEXPR (co->ext.inquire->pending);
1136 WALK_SUBEXPR (co->ext.inquire->id);
1137 WALK_SUBEXPR (co->ext.inquire->sign);
1138 WALK_SUBEXPR (co->ext.inquire->size);
1139 WALK_SUBEXPR (co->ext.inquire->round);
1143 WALK_SUBEXPR (co->ext.wait->unit);
1144 WALK_SUBEXPR (co->ext.wait->iostat);
1145 WALK_SUBEXPR (co->ext.wait->iomsg);
1146 WALK_SUBEXPR (co->ext.wait->id);
1151 WALK_SUBEXPR (co->ext.dt->io_unit);
1152 WALK_SUBEXPR (co->ext.dt->format_expr);
1153 WALK_SUBEXPR (co->ext.dt->rec);
1154 WALK_SUBEXPR (co->ext.dt->advance);
1155 WALK_SUBEXPR (co->ext.dt->iostat);
1156 WALK_SUBEXPR (co->ext.dt->size);
1157 WALK_SUBEXPR (co->ext.dt->iomsg);
1158 WALK_SUBEXPR (co->ext.dt->id);
1159 WALK_SUBEXPR (co->ext.dt->pos);
1160 WALK_SUBEXPR (co->ext.dt->asynchronous);
1161 WALK_SUBEXPR (co->ext.dt->blank);
1162 WALK_SUBEXPR (co->ext.dt->decimal);
1163 WALK_SUBEXPR (co->ext.dt->delim);
1164 WALK_SUBEXPR (co->ext.dt->pad);
1165 WALK_SUBEXPR (co->ext.dt->round);
1166 WALK_SUBEXPR (co->ext.dt->sign);
1167 WALK_SUBEXPR (co->ext.dt->extra_comma);
1171 case EXEC_OMP_PARALLEL:
1172 case EXEC_OMP_PARALLEL_DO:
1173 case EXEC_OMP_PARALLEL_SECTIONS:
1174 case EXEC_OMP_PARALLEL_WORKSHARE:
1175 case EXEC_OMP_SECTIONS:
1176 case EXEC_OMP_SINGLE:
1177 case EXEC_OMP_WORKSHARE:
1178 case EXEC_OMP_END_SINGLE:
1180 if (co->ext.omp_clauses)
1182 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
1183 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
1184 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
1191 WALK_SUBEXPR (co->expr1);
1192 WALK_SUBEXPR (co->expr2);
1193 WALK_SUBEXPR (co->expr3);
1194 WALK_SUBEXPR (co->expr4);
1195 for (b = co->block; b; b = b->block)
1197 WALK_SUBEXPR (b->expr1);
1198 WALK_SUBEXPR (b->expr2);
1199 WALK_SUBCODE (b->next);