2011-03-29 Thomas Koenig <tkoenig@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / frontend-passes.c
blob6e59c37cdbcbcd25812d8453e36e677342fb1f73
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
10 version.
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
15 for more details.
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/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "gfortran.h"
24 #include "arith.h"
25 #include "flags.h"
26 #include "dependency.h"
27 #include "constructor.h"
28 #include "opts.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
44 and counter. */
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. */
61 void
62 gfc_run_passes (gfc_namespace *ns)
64 if (optimize)
66 expr_size = 20;
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. */
82 static int
83 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
84 void *data ATTRIBUTE_UNUSED)
87 gfc_exec_op op;
89 op = (*c)->op;
91 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
92 || op == EXEC_CALL_PPC)
93 count_arglist = 1;
94 else
95 count_arglist = 0;
97 if (op == EXEC_ASSIGN)
98 optimize_assignment (*c);
99 return 0;
102 /* Callback for each gfc_expr node invoked through gfc_code_walker
103 from optimize_namespace. */
105 static int
106 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
107 void *data ATTRIBUTE_UNUSED)
109 bool function_expr;
111 if ((*e)->expr_type == EXPR_FUNCTION)
113 count_arglist ++;
114 function_expr = true;
116 else
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);
125 if (function_expr)
126 count_arglist --;
128 return 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. */
136 static int
137 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
138 void *data ATTRIBUTE_UNUSED)
140 if ((*e)->expr_type != EXPR_FUNCTION)
141 return 0;
143 /* We don't do character functions (yet). */
144 if ((*e)->ts.type == BT_CHARACTER)
145 return 0;
147 /* If we don't know the shape at compile time, we do not create a temporary
148 variable to hold the intermediate result. FIXME: Change this later when
149 allocation on assignment works for intrinsics. */
151 if ((*e)->rank > 0 && (*e)->shape == NULL)
152 return 0;
154 /* Skip the test for pure functions if -faggressive-function-elimination
155 is specified. */
156 if ((*e)->value.function.esym)
158 if ((*e)->value.function.esym->attr.allocatable)
159 return 0;
161 /* Don't create an array temporary for elemental functions. */
162 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
163 return 0;
165 /* Only eliminate potentially impure functions if the
166 user specifically requested it. */
167 if (!gfc_option.flag_aggressive_function_elimination
168 && !(*e)->value.function.esym->attr.pure
169 && !(*e)->value.function.esym->attr.implicit_pure)
170 return 0;
173 if ((*e)->value.function.isym)
175 /* Conversions are handled on the fly by the middle end,
176 transpose during trans-* stages. */
177 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
178 || (*e)->value.function.isym->id == GFC_ISYM_TRANSPOSE)
179 return 0;
181 /* Don't create an array temporary for elemental functions,
182 as this would be wasteful of memory.
183 FIXME: Create a scalar temporary during scalarization. */
184 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
185 return 0;
187 if (!(*e)->value.function.isym->pure)
188 return 0;
191 if (expr_count >= expr_size)
193 expr_size += expr_size;
194 expr_array = XRESIZEVEC(gfc_expr **, expr_array, expr_size);
196 expr_array[expr_count] = e;
197 expr_count ++;
198 return 0;
201 /* Returns a new expression (a variable) to be used in place of the old one,
202 with an an assignment statement before the current statement to set
203 the value of the variable. */
205 static gfc_expr*
206 create_var (gfc_expr * e)
208 char name[GFC_MAX_SYMBOL_LEN +1];
209 static int num = 1;
210 gfc_symtree *symtree;
211 gfc_symbol *symbol;
212 gfc_expr *result;
213 gfc_code *n;
214 int i;
216 sprintf(name, "__var_%d",num++);
217 if (gfc_get_sym_tree (name, current_ns, &symtree, false) != 0)
218 gcc_unreachable ();
220 symbol = symtree->n.sym;
221 symbol->ts = e->ts;
222 symbol->as = gfc_get_array_spec ();
223 symbol->as->rank = e->rank;
224 symbol->as->type = AS_EXPLICIT;
225 for (i=0; i<e->rank; i++)
227 gfc_expr *p, *q;
229 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
230 &(e->where));
231 mpz_set_si (p->value.integer, 1);
232 symbol->as->lower[i] = p;
234 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
235 &(e->where));
236 mpz_set (q->value.integer, e->shape[i]);
237 symbol->as->upper[i] = q;
240 symbol->attr.flavor = FL_VARIABLE;
241 symbol->attr.referenced = 1;
242 symbol->attr.dimension = e->rank > 0;
243 gfc_commit_symbol (symbol);
245 result = gfc_get_expr ();
246 result->expr_type = EXPR_VARIABLE;
247 result->ts = e->ts;
248 result->rank = e->rank;
249 result->shape = gfc_copy_shape (e->shape, e->rank);
250 result->symtree = symtree;
251 result->where = e->where;
252 if (e->rank > 0)
254 result->ref = gfc_get_ref ();
255 result->ref->type = REF_ARRAY;
256 result->ref->u.ar.type = AR_FULL;
257 result->ref->u.ar.where = e->where;
258 result->ref->u.ar.as = symbol->as;
259 if (gfc_option.warn_array_temp)
260 gfc_warning ("Creating array temporary at %L", &(e->where));
263 /* Generate the new assignment. */
264 n = XCNEW (gfc_code);
265 n->op = EXEC_ASSIGN;
266 n->loc = (*current_code)->loc;
267 n->next = *current_code;
268 n->expr1 = gfc_copy_expr (result);
269 n->expr2 = e;
270 *current_code = n;
272 return result;
275 /* Callback function for the code walker for doing common function
276 elimination. This builds up the list of functions in the expression
277 and goes through them to detect duplicates, which it then replaces
278 by variables. */
280 static int
281 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
282 void *data ATTRIBUTE_UNUSED)
284 int i,j;
285 gfc_expr *newvar;
287 expr_count = 0;
289 gfc_expr_walker (e, cfe_register_funcs, NULL);
291 /* Walk backwards through all the functions to make sure we
292 catch the leaf functions first. */
293 for (i=expr_count-1; i>=1; i--)
295 /* Skip if the function has been replaced by a variable already. */
296 if ((*(expr_array[i]))->expr_type == EXPR_VARIABLE)
297 continue;
299 newvar = NULL;
300 for (j=i-1; j>=0; j--)
302 if (gfc_dep_compare_functions(*(expr_array[i]),
303 *(expr_array[j]), true) == 0)
305 if (newvar == NULL)
306 newvar = create_var (*(expr_array[i]));
307 gfc_free (*(expr_array[j]));
308 *(expr_array[j]) = gfc_copy_expr (newvar);
311 if (newvar)
312 *(expr_array[i]) = newvar;
315 /* We did all the necessary walking in this function. */
316 *walk_subtrees = 0;
317 return 0;
320 /* Callback function for common function elimination, called from
321 gfc_code_walker. This keeps track of the current code, in order
322 to insert statements as needed. */
324 static int
325 cfe_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
326 void *data ATTRIBUTE_UNUSED)
328 current_code = c;
329 return 0;
332 /* Optimize a namespace, including all contained namespaces. */
334 static void
335 optimize_namespace (gfc_namespace *ns)
338 current_ns = ns;
340 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
341 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
343 for (ns = ns->contained; ns; ns = ns->sibling)
344 optimize_namespace (ns);
347 /* Replace code like
348 a = matmul(b,c) + d
349 with
350 a = matmul(b,c) ; a = a + d
351 where the array function is not elemental and not allocatable
352 and does not depend on the left-hand side.
355 static bool
356 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
358 gfc_expr *e;
360 e = *rhs;
361 if (e->expr_type == EXPR_OP)
363 switch (e->value.op.op)
365 /* Unary operators and exponentiation: Only look at a single
366 operand. */
367 case INTRINSIC_NOT:
368 case INTRINSIC_UPLUS:
369 case INTRINSIC_UMINUS:
370 case INTRINSIC_PARENTHESES:
371 case INTRINSIC_POWER:
372 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
373 return true;
374 break;
376 default:
377 /* Binary operators. */
378 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
379 return true;
381 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
382 return true;
384 break;
387 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
388 && ! (e->value.function.esym
389 && (e->value.function.esym->attr.elemental
390 || e->value.function.esym->attr.allocatable
391 || e->value.function.esym->ts.type != c->expr1->ts.type
392 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
393 && ! (e->value.function.isym
394 && (e->value.function.isym->elemental
395 || e->ts.type != c->expr1->ts.type
396 || e->ts.kind != c->expr1->ts.kind)))
399 gfc_code *n;
400 gfc_expr *new_expr;
402 /* Insert a new assignment statement after the current one. */
403 n = XCNEW (gfc_code);
404 n->op = EXEC_ASSIGN;
405 n->loc = c->loc;
406 n->next = c->next;
407 c->next = n;
409 n->expr1 = gfc_copy_expr (c->expr1);
410 n->expr2 = c->expr2;
411 new_expr = gfc_copy_expr (c->expr1);
412 c->expr2 = e;
413 *rhs = new_expr;
415 return true;
419 /* Nothing to optimize. */
420 return false;
423 /* Optimizations for an assignment. */
425 static void
426 optimize_assignment (gfc_code * c)
428 gfc_expr *lhs, *rhs;
430 lhs = c->expr1;
431 rhs = c->expr2;
433 /* Optimize away a = trim(b), where a is a character variable. */
435 if (lhs->ts.type == BT_CHARACTER)
437 if (rhs->expr_type == EXPR_FUNCTION &&
438 rhs->value.function.isym &&
439 rhs->value.function.isym->id == GFC_ISYM_TRIM)
441 strip_function_call (rhs);
442 optimize_assignment (c);
443 return;
447 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
448 optimize_binop_array_assignment (c, &rhs, false);
452 /* Remove an unneeded function call, modifying the expression.
453 This replaces the function call with the value of its
454 first argument. The rest of the argument list is freed. */
456 static void
457 strip_function_call (gfc_expr *e)
459 gfc_expr *e1;
460 gfc_actual_arglist *a;
462 a = e->value.function.actual;
464 /* We should have at least one argument. */
465 gcc_assert (a->expr != NULL);
467 e1 = a->expr;
469 /* Free the remaining arglist, if any. */
470 if (a->next)
471 gfc_free_actual_arglist (a->next);
473 /* Graft the argument expression onto the original function. */
474 *e = *e1;
475 gfc_free (e1);
479 /* Recursive optimization of operators. */
481 static bool
482 optimize_op (gfc_expr *e)
484 gfc_intrinsic_op op = e->value.op.op;
486 switch (op)
488 case INTRINSIC_EQ:
489 case INTRINSIC_EQ_OS:
490 case INTRINSIC_GE:
491 case INTRINSIC_GE_OS:
492 case INTRINSIC_LE:
493 case INTRINSIC_LE_OS:
494 case INTRINSIC_NE:
495 case INTRINSIC_NE_OS:
496 case INTRINSIC_GT:
497 case INTRINSIC_GT_OS:
498 case INTRINSIC_LT:
499 case INTRINSIC_LT_OS:
500 return optimize_comparison (e, op);
502 default:
503 break;
506 return false;
509 /* Optimize expressions for equality. */
511 static bool
512 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
514 gfc_expr *op1, *op2;
515 bool change;
516 int eq;
517 bool result;
519 op1 = e->value.op.op1;
520 op2 = e->value.op.op2;
522 /* Strip off unneeded TRIM calls from string comparisons. */
524 change = false;
526 if (op1->expr_type == EXPR_FUNCTION
527 && op1->value.function.isym
528 && op1->value.function.isym->id == GFC_ISYM_TRIM)
530 strip_function_call (op1);
531 change = true;
534 if (op2->expr_type == EXPR_FUNCTION
535 && op2->value.function.isym
536 && op2->value.function.isym->id == GFC_ISYM_TRIM)
538 strip_function_call (op2);
539 change = true;
542 if (change)
544 optimize_comparison (e, op);
545 return true;
548 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
549 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
550 handles them well). However, there are also cases that need a non-scalar
551 argument. For example the any intrinsic. See PR 45380. */
552 if (e->rank > 0)
553 return false;
555 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
557 if (flag_finite_math_only
558 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
559 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
561 eq = gfc_dep_compare_expr (op1, op2);
562 if (eq == -2)
564 /* Replace A // B < A // C with B < C, and A // B < C // B
565 with A < C. */
566 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
567 && op1->value.op.op == INTRINSIC_CONCAT
568 && op2->value.op.op == INTRINSIC_CONCAT)
570 gfc_expr *op1_left = op1->value.op.op1;
571 gfc_expr *op2_left = op2->value.op.op1;
572 gfc_expr *op1_right = op1->value.op.op2;
573 gfc_expr *op2_right = op2->value.op.op2;
575 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
577 /* Watch out for 'A ' // x vs. 'A' // x. */
579 if (op1_left->expr_type == EXPR_CONSTANT
580 && op2_left->expr_type == EXPR_CONSTANT
581 && op1_left->value.character.length
582 != op2_left->value.character.length)
583 return -2;
584 else
586 gfc_free (op1_left);
587 gfc_free (op2_left);
588 e->value.op.op1 = op1_right;
589 e->value.op.op2 = op2_right;
590 optimize_comparison (e, op);
591 return true;
594 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
596 gfc_free (op1_right);
597 gfc_free (op2_right);
598 e->value.op.op1 = op1_left;
599 e->value.op.op2 = op2_left;
600 optimize_comparison (e, op);
601 return true;
605 else
607 /* eq can only be -1, 0 or 1 at this point. */
608 switch (op)
610 case INTRINSIC_EQ:
611 case INTRINSIC_EQ_OS:
612 result = eq == 0;
613 break;
615 case INTRINSIC_GE:
616 case INTRINSIC_GE_OS:
617 result = eq >= 0;
618 break;
620 case INTRINSIC_LE:
621 case INTRINSIC_LE_OS:
622 result = eq <= 0;
623 break;
625 case INTRINSIC_NE:
626 case INTRINSIC_NE_OS:
627 result = eq != 0;
628 break;
630 case INTRINSIC_GT:
631 case INTRINSIC_GT_OS:
632 result = eq > 0;
633 break;
635 case INTRINSIC_LT:
636 case INTRINSIC_LT_OS:
637 result = eq < 0;
638 break;
640 default:
641 gfc_internal_error ("illegal OP in optimize_comparison");
642 break;
645 /* Replace the expression by a constant expression. The typespec
646 and where remains the way it is. */
647 gfc_free (op1);
648 gfc_free (op2);
649 e->expr_type = EXPR_CONSTANT;
650 e->value.logical = result;
651 return true;
655 return false;
658 /* Optimize a trim function by replacing it with an equivalent substring
659 involving a call to len_trim. This only works for expressions where
660 variables are trimmed. Return true if anything was modified. */
662 static bool
663 optimize_trim (gfc_expr *e)
665 gfc_expr *a;
666 gfc_ref *ref;
667 gfc_expr *fcn;
668 gfc_actual_arglist *actual_arglist, *next;
669 gfc_ref **rr = NULL;
671 /* Don't do this optimization within an argument list, because
672 otherwise aliasing issues may occur. */
674 if (count_arglist != 1)
675 return false;
677 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
678 || e->value.function.isym == NULL
679 || e->value.function.isym->id != GFC_ISYM_TRIM)
680 return false;
682 a = e->value.function.actual->expr;
684 if (a->expr_type != EXPR_VARIABLE)
685 return false;
687 /* Follow all references to find the correct place to put the newly
688 created reference. FIXME: Also handle substring references and
689 array references. Array references cause strange regressions at
690 the moment. */
692 if (a->ref)
694 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
696 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
697 return false;
701 strip_function_call (e);
703 if (e->ref == NULL)
704 rr = &(e->ref);
706 /* Create the reference. */
708 ref = gfc_get_ref ();
709 ref->type = REF_SUBSTRING;
711 /* Set the start of the reference. */
713 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
715 /* Build the function call to len_trim(x, gfc_defaul_integer_kind). */
717 fcn = gfc_get_expr ();
718 fcn->expr_type = EXPR_FUNCTION;
719 fcn->value.function.isym =
720 gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
721 actual_arglist = gfc_get_actual_arglist ();
722 actual_arglist->expr = gfc_copy_expr (e);
723 next = gfc_get_actual_arglist ();
724 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
725 gfc_default_integer_kind);
726 actual_arglist->next = next;
727 fcn->value.function.actual = actual_arglist;
729 /* Set the end of the reference to the call to len_trim. */
731 ref->u.ss.end = fcn;
732 gcc_assert (*rr == NULL);
733 *rr = ref;
734 return true;
737 #define WALK_SUBEXPR(NODE) \
738 do \
740 result = gfc_expr_walker (&(NODE), exprfn, data); \
741 if (result) \
742 return result; \
744 while (0)
745 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
747 /* Walk expression *E, calling EXPRFN on each expression in it. */
750 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
752 while (*e)
754 int walk_subtrees = 1;
755 gfc_actual_arglist *a;
756 gfc_ref *r;
757 gfc_constructor *c;
759 int result = exprfn (e, &walk_subtrees, data);
760 if (result)
761 return result;
762 if (walk_subtrees)
763 switch ((*e)->expr_type)
765 case EXPR_OP:
766 WALK_SUBEXPR ((*e)->value.op.op1);
767 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
768 break;
769 case EXPR_FUNCTION:
770 for (a = (*e)->value.function.actual; a; a = a->next)
771 WALK_SUBEXPR (a->expr);
772 break;
773 case EXPR_COMPCALL:
774 case EXPR_PPC:
775 WALK_SUBEXPR ((*e)->value.compcall.base_object);
776 for (a = (*e)->value.compcall.actual; a; a = a->next)
777 WALK_SUBEXPR (a->expr);
778 break;
780 case EXPR_STRUCTURE:
781 case EXPR_ARRAY:
782 for (c = gfc_constructor_first ((*e)->value.constructor); c;
783 c = gfc_constructor_next (c))
785 WALK_SUBEXPR (c->expr);
786 if (c->iterator != NULL)
788 WALK_SUBEXPR (c->iterator->var);
789 WALK_SUBEXPR (c->iterator->start);
790 WALK_SUBEXPR (c->iterator->end);
791 WALK_SUBEXPR (c->iterator->step);
795 if ((*e)->expr_type != EXPR_ARRAY)
796 break;
798 /* Fall through to the variable case in order to walk the
799 the reference. */
801 case EXPR_SUBSTRING:
802 case EXPR_VARIABLE:
803 for (r = (*e)->ref; r; r = r->next)
805 gfc_array_ref *ar;
806 int i;
808 switch (r->type)
810 case REF_ARRAY:
811 ar = &r->u.ar;
812 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
814 for (i=0; i< ar->dimen; i++)
816 WALK_SUBEXPR (ar->start[i]);
817 WALK_SUBEXPR (ar->end[i]);
818 WALK_SUBEXPR (ar->stride[i]);
822 break;
824 case REF_SUBSTRING:
825 WALK_SUBEXPR (r->u.ss.start);
826 WALK_SUBEXPR (r->u.ss.end);
827 break;
829 case REF_COMPONENT:
830 break;
834 default:
835 break;
837 return 0;
839 return 0;
842 #define WALK_SUBCODE(NODE) \
843 do \
845 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
846 if (result) \
847 return result; \
849 while (0)
851 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
852 on each expression in it. If any of the hooks returns non-zero, that
853 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
854 no subcodes or subexpressions are traversed. */
857 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
858 void *data)
860 for (; *c; c = &(*c)->next)
862 int walk_subtrees = 1;
863 int result = codefn (c, &walk_subtrees, data);
864 if (result)
865 return result;
867 if (walk_subtrees)
869 gfc_code *b;
870 gfc_actual_arglist *a;
872 switch ((*c)->op)
874 case EXEC_DO:
875 WALK_SUBEXPR ((*c)->ext.iterator->var);
876 WALK_SUBEXPR ((*c)->ext.iterator->start);
877 WALK_SUBEXPR ((*c)->ext.iterator->end);
878 WALK_SUBEXPR ((*c)->ext.iterator->step);
879 break;
881 case EXEC_CALL:
882 case EXEC_ASSIGN_CALL:
883 for (a = (*c)->ext.actual; a; a = a->next)
884 WALK_SUBEXPR (a->expr);
885 break;
887 case EXEC_CALL_PPC:
888 WALK_SUBEXPR ((*c)->expr1);
889 for (a = (*c)->ext.actual; a; a = a->next)
890 WALK_SUBEXPR (a->expr);
891 break;
893 case EXEC_SELECT:
894 WALK_SUBEXPR ((*c)->expr1);
895 for (b = (*c)->block; b; b = b->block)
897 gfc_case *cp;
898 for (cp = b->ext.block.case_list; cp; cp = cp->next)
900 WALK_SUBEXPR (cp->low);
901 WALK_SUBEXPR (cp->high);
903 WALK_SUBCODE (b->next);
905 continue;
907 case EXEC_ALLOCATE:
908 case EXEC_DEALLOCATE:
910 gfc_alloc *a;
911 for (a = (*c)->ext.alloc.list; a; a = a->next)
912 WALK_SUBEXPR (a->expr);
913 break;
916 case EXEC_FORALL:
918 gfc_forall_iterator *fa;
919 for (fa = (*c)->ext.forall_iterator; fa; fa = fa->next)
921 WALK_SUBEXPR (fa->var);
922 WALK_SUBEXPR (fa->start);
923 WALK_SUBEXPR (fa->end);
924 WALK_SUBEXPR (fa->stride);
926 break;
929 case EXEC_OPEN:
930 WALK_SUBEXPR ((*c)->ext.open->unit);
931 WALK_SUBEXPR ((*c)->ext.open->file);
932 WALK_SUBEXPR ((*c)->ext.open->status);
933 WALK_SUBEXPR ((*c)->ext.open->access);
934 WALK_SUBEXPR ((*c)->ext.open->form);
935 WALK_SUBEXPR ((*c)->ext.open->recl);
936 WALK_SUBEXPR ((*c)->ext.open->blank);
937 WALK_SUBEXPR ((*c)->ext.open->position);
938 WALK_SUBEXPR ((*c)->ext.open->action);
939 WALK_SUBEXPR ((*c)->ext.open->delim);
940 WALK_SUBEXPR ((*c)->ext.open->pad);
941 WALK_SUBEXPR ((*c)->ext.open->iostat);
942 WALK_SUBEXPR ((*c)->ext.open->iomsg);
943 WALK_SUBEXPR ((*c)->ext.open->convert);
944 WALK_SUBEXPR ((*c)->ext.open->decimal);
945 WALK_SUBEXPR ((*c)->ext.open->encoding);
946 WALK_SUBEXPR ((*c)->ext.open->round);
947 WALK_SUBEXPR ((*c)->ext.open->sign);
948 WALK_SUBEXPR ((*c)->ext.open->asynchronous);
949 WALK_SUBEXPR ((*c)->ext.open->id);
950 WALK_SUBEXPR ((*c)->ext.open->newunit);
951 break;
953 case EXEC_CLOSE:
954 WALK_SUBEXPR ((*c)->ext.close->unit);
955 WALK_SUBEXPR ((*c)->ext.close->status);
956 WALK_SUBEXPR ((*c)->ext.close->iostat);
957 WALK_SUBEXPR ((*c)->ext.close->iomsg);
958 break;
960 case EXEC_BACKSPACE:
961 case EXEC_ENDFILE:
962 case EXEC_REWIND:
963 case EXEC_FLUSH:
964 WALK_SUBEXPR ((*c)->ext.filepos->unit);
965 WALK_SUBEXPR ((*c)->ext.filepos->iostat);
966 WALK_SUBEXPR ((*c)->ext.filepos->iomsg);
967 break;
969 case EXEC_INQUIRE:
970 WALK_SUBEXPR ((*c)->ext.inquire->unit);
971 WALK_SUBEXPR ((*c)->ext.inquire->file);
972 WALK_SUBEXPR ((*c)->ext.inquire->iomsg);
973 WALK_SUBEXPR ((*c)->ext.inquire->iostat);
974 WALK_SUBEXPR ((*c)->ext.inquire->exist);
975 WALK_SUBEXPR ((*c)->ext.inquire->opened);
976 WALK_SUBEXPR ((*c)->ext.inquire->number);
977 WALK_SUBEXPR ((*c)->ext.inquire->named);
978 WALK_SUBEXPR ((*c)->ext.inquire->name);
979 WALK_SUBEXPR ((*c)->ext.inquire->access);
980 WALK_SUBEXPR ((*c)->ext.inquire->sequential);
981 WALK_SUBEXPR ((*c)->ext.inquire->direct);
982 WALK_SUBEXPR ((*c)->ext.inquire->form);
983 WALK_SUBEXPR ((*c)->ext.inquire->formatted);
984 WALK_SUBEXPR ((*c)->ext.inquire->unformatted);
985 WALK_SUBEXPR ((*c)->ext.inquire->recl);
986 WALK_SUBEXPR ((*c)->ext.inquire->nextrec);
987 WALK_SUBEXPR ((*c)->ext.inquire->blank);
988 WALK_SUBEXPR ((*c)->ext.inquire->position);
989 WALK_SUBEXPR ((*c)->ext.inquire->action);
990 WALK_SUBEXPR ((*c)->ext.inquire->read);
991 WALK_SUBEXPR ((*c)->ext.inquire->write);
992 WALK_SUBEXPR ((*c)->ext.inquire->readwrite);
993 WALK_SUBEXPR ((*c)->ext.inquire->delim);
994 WALK_SUBEXPR ((*c)->ext.inquire->encoding);
995 WALK_SUBEXPR ((*c)->ext.inquire->pad);
996 WALK_SUBEXPR ((*c)->ext.inquire->iolength);
997 WALK_SUBEXPR ((*c)->ext.inquire->convert);
998 WALK_SUBEXPR ((*c)->ext.inquire->strm_pos);
999 WALK_SUBEXPR ((*c)->ext.inquire->asynchronous);
1000 WALK_SUBEXPR ((*c)->ext.inquire->decimal);
1001 WALK_SUBEXPR ((*c)->ext.inquire->pending);
1002 WALK_SUBEXPR ((*c)->ext.inquire->id);
1003 WALK_SUBEXPR ((*c)->ext.inquire->sign);
1004 WALK_SUBEXPR ((*c)->ext.inquire->size);
1005 WALK_SUBEXPR ((*c)->ext.inquire->round);
1006 break;
1008 case EXEC_WAIT:
1009 WALK_SUBEXPR ((*c)->ext.wait->unit);
1010 WALK_SUBEXPR ((*c)->ext.wait->iostat);
1011 WALK_SUBEXPR ((*c)->ext.wait->iomsg);
1012 WALK_SUBEXPR ((*c)->ext.wait->id);
1013 break;
1015 case EXEC_READ:
1016 case EXEC_WRITE:
1017 WALK_SUBEXPR ((*c)->ext.dt->io_unit);
1018 WALK_SUBEXPR ((*c)->ext.dt->format_expr);
1019 WALK_SUBEXPR ((*c)->ext.dt->rec);
1020 WALK_SUBEXPR ((*c)->ext.dt->advance);
1021 WALK_SUBEXPR ((*c)->ext.dt->iostat);
1022 WALK_SUBEXPR ((*c)->ext.dt->size);
1023 WALK_SUBEXPR ((*c)->ext.dt->iomsg);
1024 WALK_SUBEXPR ((*c)->ext.dt->id);
1025 WALK_SUBEXPR ((*c)->ext.dt->pos);
1026 WALK_SUBEXPR ((*c)->ext.dt->asynchronous);
1027 WALK_SUBEXPR ((*c)->ext.dt->blank);
1028 WALK_SUBEXPR ((*c)->ext.dt->decimal);
1029 WALK_SUBEXPR ((*c)->ext.dt->delim);
1030 WALK_SUBEXPR ((*c)->ext.dt->pad);
1031 WALK_SUBEXPR ((*c)->ext.dt->round);
1032 WALK_SUBEXPR ((*c)->ext.dt->sign);
1033 WALK_SUBEXPR ((*c)->ext.dt->extra_comma);
1034 break;
1036 case EXEC_OMP_DO:
1037 case EXEC_OMP_PARALLEL:
1038 case EXEC_OMP_PARALLEL_DO:
1039 case EXEC_OMP_PARALLEL_SECTIONS:
1040 case EXEC_OMP_PARALLEL_WORKSHARE:
1041 case EXEC_OMP_SECTIONS:
1042 case EXEC_OMP_SINGLE:
1043 case EXEC_OMP_WORKSHARE:
1044 case EXEC_OMP_END_SINGLE:
1045 case EXEC_OMP_TASK:
1046 if ((*c)->ext.omp_clauses)
1048 WALK_SUBEXPR ((*c)->ext.omp_clauses->if_expr);
1049 WALK_SUBEXPR ((*c)->ext.omp_clauses->num_threads);
1050 WALK_SUBEXPR ((*c)->ext.omp_clauses->chunk_size);
1052 break;
1053 default:
1054 break;
1057 WALK_SUBEXPR ((*c)->expr1);
1058 WALK_SUBEXPR ((*c)->expr2);
1059 WALK_SUBEXPR ((*c)->expr3);
1060 for (b = (*c)->block; b; b = b->block)
1062 WALK_SUBEXPR (b->expr1);
1063 WALK_SUBEXPR (b->expr2);
1064 WALK_SUBCODE (b->next);
1068 return 0;