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_TRANSPOSE
207 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER)
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)))
576 /* Insert a new assignment statement after the current one. */
577 n = XCNEW (gfc_code);
583 n->expr1 = gfc_copy_expr (c->expr1);
585 new_expr = gfc_copy_expr (c->expr1);
593 /* Nothing to optimize. */
597 /* Remove unneeded TRIMs at the end of expressions. */
600 remove_trim (gfc_expr *rhs)
606 /* Check for a // b // trim(c). Looping is probably not
607 necessary because the parser usually generates
608 (// (// a b ) trim(c) ) , but better safe than sorry. */
610 while (rhs->expr_type == EXPR_OP
611 && rhs->value.op.op == INTRINSIC_CONCAT)
612 rhs = rhs->value.op.op2;
614 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
615 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
617 strip_function_call (rhs);
618 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
626 /* Optimizations for an assignment. */
629 optimize_assignment (gfc_code * c)
636 /* Optimize away a = trim(b), where a is a character variable. */
638 if (lhs->ts.type == BT_CHARACTER)
641 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
642 optimize_binop_array_assignment (c, &rhs, false);
646 /* Remove an unneeded function call, modifying the expression.
647 This replaces the function call with the value of its
648 first argument. The rest of the argument list is freed. */
651 strip_function_call (gfc_expr *e)
654 gfc_actual_arglist *a;
656 a = e->value.function.actual;
658 /* We should have at least one argument. */
659 gcc_assert (a->expr != NULL);
663 /* Free the remaining arglist, if any. */
665 gfc_free_actual_arglist (a->next);
667 /* Graft the argument expression onto the original function. */
673 /* Optimization of lexical comparison functions. */
676 optimize_lexical_comparison (gfc_expr *e)
678 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
681 switch (e->value.function.isym->id)
684 return optimize_comparison (e, INTRINSIC_LE);
687 return optimize_comparison (e, INTRINSIC_GE);
690 return optimize_comparison (e, INTRINSIC_GT);
693 return optimize_comparison (e, INTRINSIC_LT);
701 /* Recursive optimization of operators. */
704 optimize_op (gfc_expr *e)
706 gfc_intrinsic_op op = e->value.op.op;
711 case INTRINSIC_EQ_OS:
713 case INTRINSIC_GE_OS:
715 case INTRINSIC_LE_OS:
717 case INTRINSIC_NE_OS:
719 case INTRINSIC_GT_OS:
721 case INTRINSIC_LT_OS:
722 return optimize_comparison (e, op);
731 /* Optimize expressions for equality. */
734 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
740 gfc_actual_arglist *firstarg, *secondarg;
742 if (e->expr_type == EXPR_OP)
746 op1 = e->value.op.op1;
747 op2 = e->value.op.op2;
749 else if (e->expr_type == EXPR_FUNCTION)
751 /* One of the lexical comparision functions. */
752 firstarg = e->value.function.actual;
753 secondarg = firstarg->next;
754 op1 = firstarg->expr;
755 op2 = secondarg->expr;
760 /* Strip off unneeded TRIM calls from string comparisons. */
762 change = remove_trim (op1);
764 if (remove_trim (op2))
767 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
768 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
769 handles them well). However, there are also cases that need a non-scalar
770 argument. For example the any intrinsic. See PR 45380. */
774 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
776 if (flag_finite_math_only
777 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
778 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
780 eq = gfc_dep_compare_expr (op1, op2);
783 /* Replace A // B < A // C with B < C, and A // B < C // B
785 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
786 && op1->value.op.op == INTRINSIC_CONCAT
787 && op2->value.op.op == INTRINSIC_CONCAT)
789 gfc_expr *op1_left = op1->value.op.op1;
790 gfc_expr *op2_left = op2->value.op.op1;
791 gfc_expr *op1_right = op1->value.op.op2;
792 gfc_expr *op2_right = op2->value.op.op2;
794 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
796 /* Watch out for 'A ' // x vs. 'A' // x. */
798 if (op1_left->expr_type == EXPR_CONSTANT
799 && op2_left->expr_type == EXPR_CONSTANT
800 && op1_left->value.character.length
801 != op2_left->value.character.length)
809 firstarg->expr = op1_right;
810 secondarg->expr = op2_right;
814 e->value.op.op1 = op1_right;
815 e->value.op.op2 = op2_right;
817 optimize_comparison (e, op);
821 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
827 firstarg->expr = op1_left;
828 secondarg->expr = op2_left;
832 e->value.op.op1 = op1_left;
833 e->value.op.op2 = op2_left;
836 optimize_comparison (e, op);
843 /* eq can only be -1, 0 or 1 at this point. */
847 case INTRINSIC_EQ_OS:
852 case INTRINSIC_GE_OS:
857 case INTRINSIC_LE_OS:
862 case INTRINSIC_NE_OS:
867 case INTRINSIC_GT_OS:
872 case INTRINSIC_LT_OS:
877 gfc_internal_error ("illegal OP in optimize_comparison");
881 /* Replace the expression by a constant expression. The typespec
882 and where remains the way it is. */
885 e->expr_type = EXPR_CONSTANT;
886 e->value.logical = result;
894 /* Optimize a trim function by replacing it with an equivalent substring
895 involving a call to len_trim. This only works for expressions where
896 variables are trimmed. Return true if anything was modified. */
899 optimize_trim (gfc_expr *e)
904 gfc_actual_arglist *actual_arglist, *next;
907 /* Don't do this optimization within an argument list, because
908 otherwise aliasing issues may occur. */
910 if (count_arglist != 1)
913 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
914 || e->value.function.isym == NULL
915 || e->value.function.isym->id != GFC_ISYM_TRIM)
918 a = e->value.function.actual->expr;
920 if (a->expr_type != EXPR_VARIABLE)
923 /* Follow all references to find the correct place to put the newly
924 created reference. FIXME: Also handle substring references and
925 array references. Array references cause strange regressions at
930 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
932 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
937 strip_function_call (e);
942 /* Create the reference. */
944 ref = gfc_get_ref ();
945 ref->type = REF_SUBSTRING;
947 /* Set the start of the reference. */
949 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
951 /* Build the function call to len_trim(x, gfc_defaul_integer_kind). */
953 fcn = gfc_get_expr ();
954 fcn->expr_type = EXPR_FUNCTION;
955 fcn->value.function.isym =
956 gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
957 actual_arglist = gfc_get_actual_arglist ();
958 actual_arglist->expr = gfc_copy_expr (e);
959 next = gfc_get_actual_arglist ();
960 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
961 gfc_default_integer_kind);
962 actual_arglist->next = next;
963 fcn->value.function.actual = actual_arglist;
965 /* Set the end of the reference to the call to len_trim. */
968 gcc_assert (*rr == NULL);
973 /* Optimize minloc(b), where b is rank 1 array, into
974 (/ minloc(b, dim=1) /), and similarly for maxloc,
975 as the latter forms are expanded inline. */
978 optimize_minmaxloc (gfc_expr **e)
981 gfc_actual_arglist *a;
985 || fn->value.function.actual == NULL
986 || fn->value.function.actual->expr == NULL
987 || fn->value.function.actual->expr->rank != 1)
990 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
991 (*e)->shape = fn->shape;
994 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
996 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
997 strcpy (name, fn->value.function.name);
998 p = strstr (name, "loc0");
1000 fn->value.function.name = gfc_get_string (name);
1001 if (fn->value.function.actual->next)
1003 a = fn->value.function.actual->next;
1004 gcc_assert (a->expr == NULL);
1008 a = gfc_get_actual_arglist ();
1009 fn->value.function.actual->next = a;
1011 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
1013 mpz_set_ui (a->expr->value.integer, 1);
1016 #define WALK_SUBEXPR(NODE) \
1019 result = gfc_expr_walker (&(NODE), exprfn, data); \
1024 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
1026 /* Walk expression *E, calling EXPRFN on each expression in it. */
1029 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
1033 int walk_subtrees = 1;
1034 gfc_actual_arglist *a;
1038 int result = exprfn (e, &walk_subtrees, data);
1042 switch ((*e)->expr_type)
1045 WALK_SUBEXPR ((*e)->value.op.op1);
1046 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
1049 for (a = (*e)->value.function.actual; a; a = a->next)
1050 WALK_SUBEXPR (a->expr);
1054 WALK_SUBEXPR ((*e)->value.compcall.base_object);
1055 for (a = (*e)->value.compcall.actual; a; a = a->next)
1056 WALK_SUBEXPR (a->expr);
1059 case EXPR_STRUCTURE:
1061 for (c = gfc_constructor_first ((*e)->value.constructor); c;
1062 c = gfc_constructor_next (c))
1064 WALK_SUBEXPR (c->expr);
1065 if (c->iterator != NULL)
1067 WALK_SUBEXPR (c->iterator->var);
1068 WALK_SUBEXPR (c->iterator->start);
1069 WALK_SUBEXPR (c->iterator->end);
1070 WALK_SUBEXPR (c->iterator->step);
1074 if ((*e)->expr_type != EXPR_ARRAY)
1077 /* Fall through to the variable case in order to walk the
1080 case EXPR_SUBSTRING:
1082 for (r = (*e)->ref; r; r = r->next)
1091 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
1093 for (i=0; i< ar->dimen; i++)
1095 WALK_SUBEXPR (ar->start[i]);
1096 WALK_SUBEXPR (ar->end[i]);
1097 WALK_SUBEXPR (ar->stride[i]);
1104 WALK_SUBEXPR (r->u.ss.start);
1105 WALK_SUBEXPR (r->u.ss.end);
1121 #define WALK_SUBCODE(NODE) \
1124 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
1130 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
1131 on each expression in it. If any of the hooks returns non-zero, that
1132 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
1133 no subcodes or subexpressions are traversed. */
1136 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
1139 for (; *c; c = &(*c)->next)
1141 int walk_subtrees = 1;
1142 int result = codefn (c, &walk_subtrees, data);
1149 gfc_actual_arglist *a;
1151 gfc_association_list *alist;
1153 /* There might be statement insertions before the current code,
1154 which must not affect the expression walker. */
1162 WALK_SUBCODE (co->ext.block.ns->code);
1163 for (alist = co->ext.block.assoc; alist; alist = alist->next)
1164 WALK_SUBEXPR (alist->target);
1168 WALK_SUBEXPR (co->ext.iterator->var);
1169 WALK_SUBEXPR (co->ext.iterator->start);
1170 WALK_SUBEXPR (co->ext.iterator->end);
1171 WALK_SUBEXPR (co->ext.iterator->step);
1175 case EXEC_ASSIGN_CALL:
1176 for (a = co->ext.actual; a; a = a->next)
1177 WALK_SUBEXPR (a->expr);
1181 WALK_SUBEXPR (co->expr1);
1182 for (a = co->ext.actual; a; a = a->next)
1183 WALK_SUBEXPR (a->expr);
1187 WALK_SUBEXPR (co->expr1);
1188 for (b = co->block; b; b = b->block)
1191 for (cp = b->ext.block.case_list; cp; cp = cp->next)
1193 WALK_SUBEXPR (cp->low);
1194 WALK_SUBEXPR (cp->high);
1196 WALK_SUBCODE (b->next);
1201 case EXEC_DEALLOCATE:
1204 for (a = co->ext.alloc.list; a; a = a->next)
1205 WALK_SUBEXPR (a->expr);
1210 case EXEC_DO_CONCURRENT:
1212 gfc_forall_iterator *fa;
1213 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
1215 WALK_SUBEXPR (fa->var);
1216 WALK_SUBEXPR (fa->start);
1217 WALK_SUBEXPR (fa->end);
1218 WALK_SUBEXPR (fa->stride);
1220 if (co->op == EXEC_FORALL)
1226 WALK_SUBEXPR (co->ext.open->unit);
1227 WALK_SUBEXPR (co->ext.open->file);
1228 WALK_SUBEXPR (co->ext.open->status);
1229 WALK_SUBEXPR (co->ext.open->access);
1230 WALK_SUBEXPR (co->ext.open->form);
1231 WALK_SUBEXPR (co->ext.open->recl);
1232 WALK_SUBEXPR (co->ext.open->blank);
1233 WALK_SUBEXPR (co->ext.open->position);
1234 WALK_SUBEXPR (co->ext.open->action);
1235 WALK_SUBEXPR (co->ext.open->delim);
1236 WALK_SUBEXPR (co->ext.open->pad);
1237 WALK_SUBEXPR (co->ext.open->iostat);
1238 WALK_SUBEXPR (co->ext.open->iomsg);
1239 WALK_SUBEXPR (co->ext.open->convert);
1240 WALK_SUBEXPR (co->ext.open->decimal);
1241 WALK_SUBEXPR (co->ext.open->encoding);
1242 WALK_SUBEXPR (co->ext.open->round);
1243 WALK_SUBEXPR (co->ext.open->sign);
1244 WALK_SUBEXPR (co->ext.open->asynchronous);
1245 WALK_SUBEXPR (co->ext.open->id);
1246 WALK_SUBEXPR (co->ext.open->newunit);
1250 WALK_SUBEXPR (co->ext.close->unit);
1251 WALK_SUBEXPR (co->ext.close->status);
1252 WALK_SUBEXPR (co->ext.close->iostat);
1253 WALK_SUBEXPR (co->ext.close->iomsg);
1256 case EXEC_BACKSPACE:
1260 WALK_SUBEXPR (co->ext.filepos->unit);
1261 WALK_SUBEXPR (co->ext.filepos->iostat);
1262 WALK_SUBEXPR (co->ext.filepos->iomsg);
1266 WALK_SUBEXPR (co->ext.inquire->unit);
1267 WALK_SUBEXPR (co->ext.inquire->file);
1268 WALK_SUBEXPR (co->ext.inquire->iomsg);
1269 WALK_SUBEXPR (co->ext.inquire->iostat);
1270 WALK_SUBEXPR (co->ext.inquire->exist);
1271 WALK_SUBEXPR (co->ext.inquire->opened);
1272 WALK_SUBEXPR (co->ext.inquire->number);
1273 WALK_SUBEXPR (co->ext.inquire->named);
1274 WALK_SUBEXPR (co->ext.inquire->name);
1275 WALK_SUBEXPR (co->ext.inquire->access);
1276 WALK_SUBEXPR (co->ext.inquire->sequential);
1277 WALK_SUBEXPR (co->ext.inquire->direct);
1278 WALK_SUBEXPR (co->ext.inquire->form);
1279 WALK_SUBEXPR (co->ext.inquire->formatted);
1280 WALK_SUBEXPR (co->ext.inquire->unformatted);
1281 WALK_SUBEXPR (co->ext.inquire->recl);
1282 WALK_SUBEXPR (co->ext.inquire->nextrec);
1283 WALK_SUBEXPR (co->ext.inquire->blank);
1284 WALK_SUBEXPR (co->ext.inquire->position);
1285 WALK_SUBEXPR (co->ext.inquire->action);
1286 WALK_SUBEXPR (co->ext.inquire->read);
1287 WALK_SUBEXPR (co->ext.inquire->write);
1288 WALK_SUBEXPR (co->ext.inquire->readwrite);
1289 WALK_SUBEXPR (co->ext.inquire->delim);
1290 WALK_SUBEXPR (co->ext.inquire->encoding);
1291 WALK_SUBEXPR (co->ext.inquire->pad);
1292 WALK_SUBEXPR (co->ext.inquire->iolength);
1293 WALK_SUBEXPR (co->ext.inquire->convert);
1294 WALK_SUBEXPR (co->ext.inquire->strm_pos);
1295 WALK_SUBEXPR (co->ext.inquire->asynchronous);
1296 WALK_SUBEXPR (co->ext.inquire->decimal);
1297 WALK_SUBEXPR (co->ext.inquire->pending);
1298 WALK_SUBEXPR (co->ext.inquire->id);
1299 WALK_SUBEXPR (co->ext.inquire->sign);
1300 WALK_SUBEXPR (co->ext.inquire->size);
1301 WALK_SUBEXPR (co->ext.inquire->round);
1305 WALK_SUBEXPR (co->ext.wait->unit);
1306 WALK_SUBEXPR (co->ext.wait->iostat);
1307 WALK_SUBEXPR (co->ext.wait->iomsg);
1308 WALK_SUBEXPR (co->ext.wait->id);
1313 WALK_SUBEXPR (co->ext.dt->io_unit);
1314 WALK_SUBEXPR (co->ext.dt->format_expr);
1315 WALK_SUBEXPR (co->ext.dt->rec);
1316 WALK_SUBEXPR (co->ext.dt->advance);
1317 WALK_SUBEXPR (co->ext.dt->iostat);
1318 WALK_SUBEXPR (co->ext.dt->size);
1319 WALK_SUBEXPR (co->ext.dt->iomsg);
1320 WALK_SUBEXPR (co->ext.dt->id);
1321 WALK_SUBEXPR (co->ext.dt->pos);
1322 WALK_SUBEXPR (co->ext.dt->asynchronous);
1323 WALK_SUBEXPR (co->ext.dt->blank);
1324 WALK_SUBEXPR (co->ext.dt->decimal);
1325 WALK_SUBEXPR (co->ext.dt->delim);
1326 WALK_SUBEXPR (co->ext.dt->pad);
1327 WALK_SUBEXPR (co->ext.dt->round);
1328 WALK_SUBEXPR (co->ext.dt->sign);
1329 WALK_SUBEXPR (co->ext.dt->extra_comma);
1333 case EXEC_OMP_PARALLEL:
1334 case EXEC_OMP_PARALLEL_DO:
1335 case EXEC_OMP_PARALLEL_SECTIONS:
1336 case EXEC_OMP_PARALLEL_WORKSHARE:
1337 case EXEC_OMP_SECTIONS:
1338 case EXEC_OMP_SINGLE:
1339 case EXEC_OMP_WORKSHARE:
1340 case EXEC_OMP_END_SINGLE:
1342 if (co->ext.omp_clauses)
1344 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
1345 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
1346 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
1347 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
1354 WALK_SUBEXPR (co->expr1);
1355 WALK_SUBEXPR (co->expr2);
1356 WALK_SUBEXPR (co->expr3);
1357 WALK_SUBEXPR (co->expr4);
1358 for (b = co->block; b; b = b->block)
1360 WALK_SUBEXPR (b->expr1);
1361 WALK_SUBEXPR (b->expr2);
1362 WALK_SUBCODE (b->next);
1365 if (co->op == EXEC_FORALL)