1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010, 2011 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 *);
39 static void optimize_minmaxloc (gfc_expr **);
41 /* How deep we are inside an argument list. */
43 static int count_arglist;
45 /* Pointer to an array of gfc_expr ** we operate on, plus its size
48 static gfc_expr ***expr_array;
49 static int expr_size, expr_count;
51 /* Pointer to the gfc_code we currently work on - to be able to insert
52 a block before the statement. */
54 static gfc_code **current_code;
56 /* Pointer to the block to be inserted, and the statement we are
57 changing within the block. */
59 static gfc_code *inserted_block, **changed_statement;
61 /* The namespace we are currently dealing with. */
63 static gfc_namespace *current_ns;
65 /* If we are within any forall loop. */
67 static int forall_level;
69 /* Entry point - run all passes for a namespace. So far, only an
70 optimization pass is run. */
73 gfc_run_passes (gfc_namespace *ns)
75 if (gfc_option.flag_frontend_optimize)
78 expr_array = XNEWVEC(gfc_expr **, expr_size);
80 optimize_namespace (ns);
81 if (gfc_option.dump_fortran_optimized)
82 gfc_dump_parse_tree (ns, stdout);
84 XDELETEVEC (expr_array);
88 /* Callback for each gfc_code node invoked through gfc_code_walker
89 from optimize_namespace. */
92 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
93 void *data ATTRIBUTE_UNUSED)
100 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
101 || op == EXEC_CALL_PPC)
106 if (op == EXEC_ASSIGN)
107 optimize_assignment (*c);
111 /* Callback for each gfc_expr node invoked through gfc_code_walker
112 from optimize_namespace. */
115 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
116 void *data ATTRIBUTE_UNUSED)
120 if ((*e)->expr_type == EXPR_FUNCTION)
123 function_expr = true;
126 function_expr = false;
128 if (optimize_trim (*e))
129 gfc_simplify_expr (*e, 0);
131 if (optimize_lexical_comparison (*e))
132 gfc_simplify_expr (*e, 0);
134 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
135 gfc_simplify_expr (*e, 0);
137 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
138 switch ((*e)->value.function.isym->id)
140 case GFC_ISYM_MINLOC:
141 case GFC_ISYM_MAXLOC:
142 optimize_minmaxloc (e);
155 /* Callback function for common function elimination, called from cfe_expr_0.
156 Put all eligible function expressions into expr_array. */
159 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
160 void *data ATTRIBUTE_UNUSED)
163 if ((*e)->expr_type != EXPR_FUNCTION)
166 /* We don't do character functions with unknown charlens. */
167 if ((*e)->ts.type == BT_CHARACTER
168 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
169 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
172 /* We don't do function elimination within FORALL statements, it can
173 lead to wrong-code in certain circumstances. */
175 if (forall_level > 0)
178 /* If we don't know the shape at compile time, we create an allocatable
179 temporary variable to hold the intermediate result, but only if
180 allocation on assignment is active. */
182 if ((*e)->rank > 0 && (*e)->shape == NULL && !gfc_option.flag_realloc_lhs)
185 /* Skip the test for pure functions if -faggressive-function-elimination
187 if ((*e)->value.function.esym)
189 /* Don't create an array temporary for elemental functions. */
190 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
193 /* Only eliminate potentially impure functions if the
194 user specifically requested it. */
195 if (!gfc_option.flag_aggressive_function_elimination
196 && !(*e)->value.function.esym->attr.pure
197 && !(*e)->value.function.esym->attr.implicit_pure)
201 if ((*e)->value.function.isym)
203 /* Conversions are handled on the fly by the middle end,
204 transpose during trans-* stages and TRANSFER by the middle end. */
205 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
206 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
207 || gfc_inline_intrinsic_function_p (*e))
210 /* Don't create an array temporary for elemental functions,
211 as this would be wasteful of memory.
212 FIXME: Create a scalar temporary during scalarization. */
213 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
216 if (!(*e)->value.function.isym->pure)
220 if (expr_count >= expr_size)
222 expr_size += expr_size;
223 expr_array = XRESIZEVEC(gfc_expr **, expr_array, expr_size);
225 expr_array[expr_count] = e;
230 /* Returns a new expression (a variable) to be used in place of the old one,
231 with an an assignment statement before the current statement to set
232 the value of the variable. Creates a new BLOCK for the statement if
233 that hasn't already been done and puts the statement, plus the
234 newly created variables, in that block. */
237 create_var (gfc_expr * e)
239 char name[GFC_MAX_SYMBOL_LEN +1];
241 gfc_symtree *symtree;
248 /* If the block hasn't already been created, do so. */
249 if (inserted_block == NULL)
251 inserted_block = XCNEW (gfc_code);
252 inserted_block->op = EXEC_BLOCK;
253 inserted_block->loc = (*current_code)->loc;
254 ns = gfc_build_block_ns (current_ns);
255 inserted_block->ext.block.ns = ns;
256 inserted_block->ext.block.assoc = NULL;
258 ns->code = *current_code;
259 inserted_block->next = (*current_code)->next;
260 changed_statement = &(inserted_block->ext.block.ns->code);
261 (*current_code)->next = NULL;
262 /* Insert the BLOCK at the right position. */
263 *current_code = inserted_block;
264 ns->parent = current_ns;
267 ns = inserted_block->ext.block.ns;
269 sprintf(name, "__var_%d",num++);
270 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
273 symbol = symtree->n.sym;
278 symbol->as = gfc_get_array_spec ();
279 symbol->as->rank = e->rank;
281 if (e->shape == NULL)
283 /* We don't know the shape at compile time, so we use an
285 symbol->as->type = AS_DEFERRED;
286 symbol->attr.allocatable = 1;
290 symbol->as->type = AS_EXPLICIT;
291 /* Copy the shape. */
292 for (i=0; i<e->rank; i++)
296 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
298 mpz_set_si (p->value.integer, 1);
299 symbol->as->lower[i] = p;
301 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
303 mpz_set (q->value.integer, e->shape[i]);
304 symbol->as->upper[i] = q;
309 symbol->attr.flavor = FL_VARIABLE;
310 symbol->attr.referenced = 1;
311 symbol->attr.dimension = e->rank > 0;
312 gfc_commit_symbol (symbol);
314 result = gfc_get_expr ();
315 result->expr_type = EXPR_VARIABLE;
317 result->rank = e->rank;
318 result->shape = gfc_copy_shape (e->shape, e->rank);
319 result->symtree = symtree;
320 result->where = e->where;
323 result->ref = gfc_get_ref ();
324 result->ref->type = REF_ARRAY;
325 result->ref->u.ar.type = AR_FULL;
326 result->ref->u.ar.where = e->where;
327 result->ref->u.ar.as = symbol->as;
328 if (gfc_option.warn_array_temp)
329 gfc_warning ("Creating array temporary at %L", &(e->where));
332 /* Generate the new assignment. */
333 n = XCNEW (gfc_code);
335 n->loc = (*current_code)->loc;
336 n->next = *changed_statement;
337 n->expr1 = gfc_copy_expr (result);
339 *changed_statement = n;
344 /* Warn about function elimination. */
347 warn_function_elimination (gfc_expr *e)
349 if (e->expr_type != EXPR_FUNCTION)
351 if (e->value.function.esym)
352 gfc_warning ("Removing call to function '%s' at %L",
353 e->value.function.esym->name, &(e->where));
354 else if (e->value.function.isym)
355 gfc_warning ("Removing call to function '%s' at %L",
356 e->value.function.isym->name, &(e->where));
358 /* Callback function for the code walker for doing common function
359 elimination. This builds up the list of functions in the expression
360 and goes through them to detect duplicates, which it then replaces
364 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
365 void *data ATTRIBUTE_UNUSED)
372 gfc_expr_walker (e, cfe_register_funcs, NULL);
374 /* Walk through all the functions. */
376 for (i=1; i<expr_count; i++)
378 /* Skip if the function has been replaced by a variable already. */
379 if ((*(expr_array[i]))->expr_type == EXPR_VARIABLE)
385 if (gfc_dep_compare_functions(*(expr_array[i]),
386 *(expr_array[j]), true) == 0)
389 newvar = create_var (*(expr_array[i]));
391 if (gfc_option.warn_function_elimination)
392 warn_function_elimination (*(expr_array[j]));
394 free (*(expr_array[j]));
395 *(expr_array[j]) = gfc_copy_expr (newvar);
399 *(expr_array[i]) = newvar;
402 /* We did all the necessary walking in this function. */
407 /* Callback function for common function elimination, called from
408 gfc_code_walker. This keeps track of the current code, in order
409 to insert statements as needed. */
412 cfe_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
413 void *data ATTRIBUTE_UNUSED)
416 inserted_block = NULL;
417 changed_statement = NULL;
421 /* Dummy function for expression call back, for use when we
422 really don't want to do any walking. */
425 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
426 void *data ATTRIBUTE_UNUSED)
432 /* Code callback function for converting
439 This is because common function elimination would otherwise place the
440 temporary variables outside the loop. */
443 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
444 void *data ATTRIBUTE_UNUSED)
447 gfc_code *c_if1, *c_if2, *c_exit;
449 gfc_expr *e_not, *e_cond;
451 if (co->op != EXEC_DO_WHILE)
454 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
459 /* Generate the condition of the if statement, which is .not. the original
461 e_not = gfc_get_expr ();
462 e_not->ts = e_cond->ts;
463 e_not->where = e_cond->where;
464 e_not->expr_type = EXPR_OP;
465 e_not->value.op.op = INTRINSIC_NOT;
466 e_not->value.op.op1 = e_cond;
468 /* Generate the EXIT statement. */
469 c_exit = XCNEW (gfc_code);
470 c_exit->op = EXEC_EXIT;
471 c_exit->ext.which_construct = co;
472 c_exit->loc = co->loc;
474 /* Generate the IF statement. */
475 c_if2 = XCNEW (gfc_code);
477 c_if2->expr1 = e_not;
478 c_if2->next = c_exit;
479 c_if2->loc = co->loc;
481 /* ... plus the one to chain it to. */
482 c_if1 = XCNEW (gfc_code);
484 c_if1->block = c_if2;
485 c_if1->loc = co->loc;
487 /* Make the DO WHILE loop into a DO block by replacing the condition
488 with a true constant. */
489 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
491 /* Hang the generated if statement into the loop body. */
493 loopblock = co->block->next;
494 co->block->next = c_if1;
495 c_if1->next = loopblock;
500 /* Optimize a namespace, including all contained namespaces. */
503 optimize_namespace (gfc_namespace *ns)
509 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
510 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
511 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
513 /* BLOCKs are handled in the expression walker below. */
514 for (ns = ns->contained; ns; ns = ns->sibling)
516 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
517 optimize_namespace (ns);
524 a = matmul(b,c) ; a = a + d
525 where the array function is not elemental and not allocatable
526 and does not depend on the left-hand side.
530 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
535 if (e->expr_type == EXPR_OP)
537 switch (e->value.op.op)
539 /* Unary operators and exponentiation: Only look at a single
542 case INTRINSIC_UPLUS:
543 case INTRINSIC_UMINUS:
544 case INTRINSIC_PARENTHESES:
545 case INTRINSIC_POWER:
546 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
551 /* Binary operators. */
552 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
555 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
561 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
562 && ! (e->value.function.esym
563 && (e->value.function.esym->attr.elemental
564 || e->value.function.esym->attr.allocatable
565 || e->value.function.esym->ts.type != c->expr1->ts.type
566 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
567 && ! (e->value.function.isym
568 && (e->value.function.isym->elemental
569 || e->ts.type != c->expr1->ts.type
570 || e->ts.kind != c->expr1->ts.kind))
571 && ! gfc_inline_intrinsic_function_p (e))
577 /* Insert a new assignment statement after the current one. */
578 n = XCNEW (gfc_code);
584 n->expr1 = gfc_copy_expr (c->expr1);
586 new_expr = gfc_copy_expr (c->expr1);
594 /* Nothing to optimize. */
598 /* Remove unneeded TRIMs at the end of expressions. */
601 remove_trim (gfc_expr *rhs)
607 /* Check for a // b // trim(c). Looping is probably not
608 necessary because the parser usually generates
609 (// (// a b ) trim(c) ) , but better safe than sorry. */
611 while (rhs->expr_type == EXPR_OP
612 && rhs->value.op.op == INTRINSIC_CONCAT)
613 rhs = rhs->value.op.op2;
615 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
616 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
618 strip_function_call (rhs);
619 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
627 /* Optimizations for an assignment. */
630 optimize_assignment (gfc_code * c)
637 /* Optimize away a = trim(b), where a is a character variable. */
639 if (lhs->ts.type == BT_CHARACTER)
642 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
643 optimize_binop_array_assignment (c, &rhs, false);
647 /* Remove an unneeded function call, modifying the expression.
648 This replaces the function call with the value of its
649 first argument. The rest of the argument list is freed. */
652 strip_function_call (gfc_expr *e)
655 gfc_actual_arglist *a;
657 a = e->value.function.actual;
659 /* We should have at least one argument. */
660 gcc_assert (a->expr != NULL);
664 /* Free the remaining arglist, if any. */
666 gfc_free_actual_arglist (a->next);
668 /* Graft the argument expression onto the original function. */
674 /* Optimization of lexical comparison functions. */
677 optimize_lexical_comparison (gfc_expr *e)
679 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
682 switch (e->value.function.isym->id)
685 return optimize_comparison (e, INTRINSIC_LE);
688 return optimize_comparison (e, INTRINSIC_GE);
691 return optimize_comparison (e, INTRINSIC_GT);
694 return optimize_comparison (e, INTRINSIC_LT);
702 /* Recursive optimization of operators. */
705 optimize_op (gfc_expr *e)
707 gfc_intrinsic_op op = e->value.op.op;
712 case INTRINSIC_EQ_OS:
714 case INTRINSIC_GE_OS:
716 case INTRINSIC_LE_OS:
718 case INTRINSIC_NE_OS:
720 case INTRINSIC_GT_OS:
722 case INTRINSIC_LT_OS:
723 return optimize_comparison (e, op);
732 /* Optimize expressions for equality. */
735 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
741 gfc_actual_arglist *firstarg, *secondarg;
743 if (e->expr_type == EXPR_OP)
747 op1 = e->value.op.op1;
748 op2 = e->value.op.op2;
750 else if (e->expr_type == EXPR_FUNCTION)
752 /* One of the lexical comparision functions. */
753 firstarg = e->value.function.actual;
754 secondarg = firstarg->next;
755 op1 = firstarg->expr;
756 op2 = secondarg->expr;
761 /* Strip off unneeded TRIM calls from string comparisons. */
763 change = remove_trim (op1);
765 if (remove_trim (op2))
768 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
769 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
770 handles them well). However, there are also cases that need a non-scalar
771 argument. For example the any intrinsic. See PR 45380. */
775 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
777 if (flag_finite_math_only
778 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
779 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
781 eq = gfc_dep_compare_expr (op1, op2);
784 /* Replace A // B < A // C with B < C, and A // B < C // B
786 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
787 && op1->value.op.op == INTRINSIC_CONCAT
788 && op2->value.op.op == INTRINSIC_CONCAT)
790 gfc_expr *op1_left = op1->value.op.op1;
791 gfc_expr *op2_left = op2->value.op.op1;
792 gfc_expr *op1_right = op1->value.op.op2;
793 gfc_expr *op2_right = op2->value.op.op2;
795 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
797 /* Watch out for 'A ' // x vs. 'A' // x. */
799 if (op1_left->expr_type == EXPR_CONSTANT
800 && op2_left->expr_type == EXPR_CONSTANT
801 && op1_left->value.character.length
802 != op2_left->value.character.length)
810 firstarg->expr = op1_right;
811 secondarg->expr = op2_right;
815 e->value.op.op1 = op1_right;
816 e->value.op.op2 = op2_right;
818 optimize_comparison (e, op);
822 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
828 firstarg->expr = op1_left;
829 secondarg->expr = op2_left;
833 e->value.op.op1 = op1_left;
834 e->value.op.op2 = op2_left;
837 optimize_comparison (e, op);
844 /* eq can only be -1, 0 or 1 at this point. */
848 case INTRINSIC_EQ_OS:
853 case INTRINSIC_GE_OS:
858 case INTRINSIC_LE_OS:
863 case INTRINSIC_NE_OS:
868 case INTRINSIC_GT_OS:
873 case INTRINSIC_LT_OS:
878 gfc_internal_error ("illegal OP in optimize_comparison");
882 /* Replace the expression by a constant expression. The typespec
883 and where remains the way it is. */
886 e->expr_type = EXPR_CONSTANT;
887 e->value.logical = result;
895 /* Optimize a trim function by replacing it with an equivalent substring
896 involving a call to len_trim. This only works for expressions where
897 variables are trimmed. Return true if anything was modified. */
900 optimize_trim (gfc_expr *e)
905 gfc_actual_arglist *actual_arglist, *next;
908 /* Don't do this optimization within an argument list, because
909 otherwise aliasing issues may occur. */
911 if (count_arglist != 1)
914 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
915 || e->value.function.isym == NULL
916 || e->value.function.isym->id != GFC_ISYM_TRIM)
919 a = e->value.function.actual->expr;
921 if (a->expr_type != EXPR_VARIABLE)
924 /* Follow all references to find the correct place to put the newly
925 created reference. FIXME: Also handle substring references and
926 array references. Array references cause strange regressions at
931 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
933 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
938 strip_function_call (e);
943 /* Create the reference. */
945 ref = gfc_get_ref ();
946 ref->type = REF_SUBSTRING;
948 /* Set the start of the reference. */
950 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
952 /* Build the function call to len_trim(x, gfc_defaul_integer_kind). */
954 fcn = gfc_get_expr ();
955 fcn->expr_type = EXPR_FUNCTION;
956 fcn->value.function.isym =
957 gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
958 actual_arglist = gfc_get_actual_arglist ();
959 actual_arglist->expr = gfc_copy_expr (e);
960 next = gfc_get_actual_arglist ();
961 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
962 gfc_default_integer_kind);
963 actual_arglist->next = next;
964 fcn->value.function.actual = actual_arglist;
966 /* Set the end of the reference to the call to len_trim. */
969 gcc_assert (*rr == NULL);
974 /* Optimize minloc(b), where b is rank 1 array, into
975 (/ minloc(b, dim=1) /), and similarly for maxloc,
976 as the latter forms are expanded inline. */
979 optimize_minmaxloc (gfc_expr **e)
982 gfc_actual_arglist *a;
986 || fn->value.function.actual == NULL
987 || fn->value.function.actual->expr == NULL
988 || fn->value.function.actual->expr->rank != 1)
991 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
992 (*e)->shape = fn->shape;
995 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
997 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
998 strcpy (name, fn->value.function.name);
999 p = strstr (name, "loc0");
1001 fn->value.function.name = gfc_get_string (name);
1002 if (fn->value.function.actual->next)
1004 a = fn->value.function.actual->next;
1005 gcc_assert (a->expr == NULL);
1009 a = gfc_get_actual_arglist ();
1010 fn->value.function.actual->next = a;
1012 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
1014 mpz_set_ui (a->expr->value.integer, 1);
1017 #define WALK_SUBEXPR(NODE) \
1020 result = gfc_expr_walker (&(NODE), exprfn, data); \
1025 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
1027 /* Walk expression *E, calling EXPRFN on each expression in it. */
1030 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
1034 int walk_subtrees = 1;
1035 gfc_actual_arglist *a;
1039 int result = exprfn (e, &walk_subtrees, data);
1043 switch ((*e)->expr_type)
1046 WALK_SUBEXPR ((*e)->value.op.op1);
1047 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
1050 for (a = (*e)->value.function.actual; a; a = a->next)
1051 WALK_SUBEXPR (a->expr);
1055 WALK_SUBEXPR ((*e)->value.compcall.base_object);
1056 for (a = (*e)->value.compcall.actual; a; a = a->next)
1057 WALK_SUBEXPR (a->expr);
1060 case EXPR_STRUCTURE:
1062 for (c = gfc_constructor_first ((*e)->value.constructor); c;
1063 c = gfc_constructor_next (c))
1065 WALK_SUBEXPR (c->expr);
1066 if (c->iterator != NULL)
1068 WALK_SUBEXPR (c->iterator->var);
1069 WALK_SUBEXPR (c->iterator->start);
1070 WALK_SUBEXPR (c->iterator->end);
1071 WALK_SUBEXPR (c->iterator->step);
1075 if ((*e)->expr_type != EXPR_ARRAY)
1078 /* Fall through to the variable case in order to walk the
1081 case EXPR_SUBSTRING:
1083 for (r = (*e)->ref; r; r = r->next)
1092 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
1094 for (i=0; i< ar->dimen; i++)
1096 WALK_SUBEXPR (ar->start[i]);
1097 WALK_SUBEXPR (ar->end[i]);
1098 WALK_SUBEXPR (ar->stride[i]);
1105 WALK_SUBEXPR (r->u.ss.start);
1106 WALK_SUBEXPR (r->u.ss.end);
1122 #define WALK_SUBCODE(NODE) \
1125 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
1131 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
1132 on each expression in it. If any of the hooks returns non-zero, that
1133 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
1134 no subcodes or subexpressions are traversed. */
1137 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
1140 for (; *c; c = &(*c)->next)
1142 int walk_subtrees = 1;
1143 int result = codefn (c, &walk_subtrees, data);
1150 gfc_actual_arglist *a;
1152 gfc_association_list *alist;
1154 /* There might be statement insertions before the current code,
1155 which must not affect the expression walker. */
1163 WALK_SUBCODE (co->ext.block.ns->code);
1164 for (alist = co->ext.block.assoc; alist; alist = alist->next)
1165 WALK_SUBEXPR (alist->target);
1169 WALK_SUBEXPR (co->ext.iterator->var);
1170 WALK_SUBEXPR (co->ext.iterator->start);
1171 WALK_SUBEXPR (co->ext.iterator->end);
1172 WALK_SUBEXPR (co->ext.iterator->step);
1176 case EXEC_ASSIGN_CALL:
1177 for (a = co->ext.actual; a; a = a->next)
1178 WALK_SUBEXPR (a->expr);
1182 WALK_SUBEXPR (co->expr1);
1183 for (a = co->ext.actual; a; a = a->next)
1184 WALK_SUBEXPR (a->expr);
1188 WALK_SUBEXPR (co->expr1);
1189 for (b = co->block; b; b = b->block)
1192 for (cp = b->ext.block.case_list; cp; cp = cp->next)
1194 WALK_SUBEXPR (cp->low);
1195 WALK_SUBEXPR (cp->high);
1197 WALK_SUBCODE (b->next);
1202 case EXEC_DEALLOCATE:
1205 for (a = co->ext.alloc.list; a; a = a->next)
1206 WALK_SUBEXPR (a->expr);
1211 case EXEC_DO_CONCURRENT:
1213 gfc_forall_iterator *fa;
1214 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
1216 WALK_SUBEXPR (fa->var);
1217 WALK_SUBEXPR (fa->start);
1218 WALK_SUBEXPR (fa->end);
1219 WALK_SUBEXPR (fa->stride);
1221 if (co->op == EXEC_FORALL)
1227 WALK_SUBEXPR (co->ext.open->unit);
1228 WALK_SUBEXPR (co->ext.open->file);
1229 WALK_SUBEXPR (co->ext.open->status);
1230 WALK_SUBEXPR (co->ext.open->access);
1231 WALK_SUBEXPR (co->ext.open->form);
1232 WALK_SUBEXPR (co->ext.open->recl);
1233 WALK_SUBEXPR (co->ext.open->blank);
1234 WALK_SUBEXPR (co->ext.open->position);
1235 WALK_SUBEXPR (co->ext.open->action);
1236 WALK_SUBEXPR (co->ext.open->delim);
1237 WALK_SUBEXPR (co->ext.open->pad);
1238 WALK_SUBEXPR (co->ext.open->iostat);
1239 WALK_SUBEXPR (co->ext.open->iomsg);
1240 WALK_SUBEXPR (co->ext.open->convert);
1241 WALK_SUBEXPR (co->ext.open->decimal);
1242 WALK_SUBEXPR (co->ext.open->encoding);
1243 WALK_SUBEXPR (co->ext.open->round);
1244 WALK_SUBEXPR (co->ext.open->sign);
1245 WALK_SUBEXPR (co->ext.open->asynchronous);
1246 WALK_SUBEXPR (co->ext.open->id);
1247 WALK_SUBEXPR (co->ext.open->newunit);
1251 WALK_SUBEXPR (co->ext.close->unit);
1252 WALK_SUBEXPR (co->ext.close->status);
1253 WALK_SUBEXPR (co->ext.close->iostat);
1254 WALK_SUBEXPR (co->ext.close->iomsg);
1257 case EXEC_BACKSPACE:
1261 WALK_SUBEXPR (co->ext.filepos->unit);
1262 WALK_SUBEXPR (co->ext.filepos->iostat);
1263 WALK_SUBEXPR (co->ext.filepos->iomsg);
1267 WALK_SUBEXPR (co->ext.inquire->unit);
1268 WALK_SUBEXPR (co->ext.inquire->file);
1269 WALK_SUBEXPR (co->ext.inquire->iomsg);
1270 WALK_SUBEXPR (co->ext.inquire->iostat);
1271 WALK_SUBEXPR (co->ext.inquire->exist);
1272 WALK_SUBEXPR (co->ext.inquire->opened);
1273 WALK_SUBEXPR (co->ext.inquire->number);
1274 WALK_SUBEXPR (co->ext.inquire->named);
1275 WALK_SUBEXPR (co->ext.inquire->name);
1276 WALK_SUBEXPR (co->ext.inquire->access);
1277 WALK_SUBEXPR (co->ext.inquire->sequential);
1278 WALK_SUBEXPR (co->ext.inquire->direct);
1279 WALK_SUBEXPR (co->ext.inquire->form);
1280 WALK_SUBEXPR (co->ext.inquire->formatted);
1281 WALK_SUBEXPR (co->ext.inquire->unformatted);
1282 WALK_SUBEXPR (co->ext.inquire->recl);
1283 WALK_SUBEXPR (co->ext.inquire->nextrec);
1284 WALK_SUBEXPR (co->ext.inquire->blank);
1285 WALK_SUBEXPR (co->ext.inquire->position);
1286 WALK_SUBEXPR (co->ext.inquire->action);
1287 WALK_SUBEXPR (co->ext.inquire->read);
1288 WALK_SUBEXPR (co->ext.inquire->write);
1289 WALK_SUBEXPR (co->ext.inquire->readwrite);
1290 WALK_SUBEXPR (co->ext.inquire->delim);
1291 WALK_SUBEXPR (co->ext.inquire->encoding);
1292 WALK_SUBEXPR (co->ext.inquire->pad);
1293 WALK_SUBEXPR (co->ext.inquire->iolength);
1294 WALK_SUBEXPR (co->ext.inquire->convert);
1295 WALK_SUBEXPR (co->ext.inquire->strm_pos);
1296 WALK_SUBEXPR (co->ext.inquire->asynchronous);
1297 WALK_SUBEXPR (co->ext.inquire->decimal);
1298 WALK_SUBEXPR (co->ext.inquire->pending);
1299 WALK_SUBEXPR (co->ext.inquire->id);
1300 WALK_SUBEXPR (co->ext.inquire->sign);
1301 WALK_SUBEXPR (co->ext.inquire->size);
1302 WALK_SUBEXPR (co->ext.inquire->round);
1306 WALK_SUBEXPR (co->ext.wait->unit);
1307 WALK_SUBEXPR (co->ext.wait->iostat);
1308 WALK_SUBEXPR (co->ext.wait->iomsg);
1309 WALK_SUBEXPR (co->ext.wait->id);
1314 WALK_SUBEXPR (co->ext.dt->io_unit);
1315 WALK_SUBEXPR (co->ext.dt->format_expr);
1316 WALK_SUBEXPR (co->ext.dt->rec);
1317 WALK_SUBEXPR (co->ext.dt->advance);
1318 WALK_SUBEXPR (co->ext.dt->iostat);
1319 WALK_SUBEXPR (co->ext.dt->size);
1320 WALK_SUBEXPR (co->ext.dt->iomsg);
1321 WALK_SUBEXPR (co->ext.dt->id);
1322 WALK_SUBEXPR (co->ext.dt->pos);
1323 WALK_SUBEXPR (co->ext.dt->asynchronous);
1324 WALK_SUBEXPR (co->ext.dt->blank);
1325 WALK_SUBEXPR (co->ext.dt->decimal);
1326 WALK_SUBEXPR (co->ext.dt->delim);
1327 WALK_SUBEXPR (co->ext.dt->pad);
1328 WALK_SUBEXPR (co->ext.dt->round);
1329 WALK_SUBEXPR (co->ext.dt->sign);
1330 WALK_SUBEXPR (co->ext.dt->extra_comma);
1334 case EXEC_OMP_PARALLEL:
1335 case EXEC_OMP_PARALLEL_DO:
1336 case EXEC_OMP_PARALLEL_SECTIONS:
1337 case EXEC_OMP_PARALLEL_WORKSHARE:
1338 case EXEC_OMP_SECTIONS:
1339 case EXEC_OMP_SINGLE:
1340 case EXEC_OMP_WORKSHARE:
1341 case EXEC_OMP_END_SINGLE:
1343 if (co->ext.omp_clauses)
1345 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
1346 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
1347 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
1348 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
1355 WALK_SUBEXPR (co->expr1);
1356 WALK_SUBEXPR (co->expr2);
1357 WALK_SUBEXPR (co->expr3);
1358 WALK_SUBEXPR (co->expr4);
1359 for (b = co->block; b; b = b->block)
1361 WALK_SUBEXPR (b->expr1);
1362 WALK_SUBEXPR (b->expr2);
1363 WALK_SUBCODE (b->next);
1366 if (co->op == EXEC_FORALL)