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 /* Keep track of whether we are within an OMP workshare. */
71 static bool in_omp_workshare;
73 /* Keep track of iterators for array constructors. */
75 static int iterator_level;
77 /* Entry point - run all passes for a namespace. So far, only an
78 optimization pass is run. */
81 gfc_run_passes (gfc_namespace *ns)
83 if (gfc_option.flag_frontend_optimize)
86 expr_array = XNEWVEC(gfc_expr **, expr_size);
88 optimize_namespace (ns);
89 if (gfc_option.dump_fortran_optimized)
90 gfc_dump_parse_tree (ns, stdout);
92 XDELETEVEC (expr_array);
96 /* Callback for each gfc_code node invoked through gfc_code_walker
97 from optimize_namespace. */
100 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
101 void *data ATTRIBUTE_UNUSED)
108 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
109 || op == EXEC_CALL_PPC)
114 if (op == EXEC_ASSIGN)
115 optimize_assignment (*c);
119 /* Callback for each gfc_expr node invoked through gfc_code_walker
120 from optimize_namespace. */
123 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
124 void *data ATTRIBUTE_UNUSED)
128 if ((*e)->expr_type == EXPR_FUNCTION)
131 function_expr = true;
134 function_expr = false;
136 if (optimize_trim (*e))
137 gfc_simplify_expr (*e, 0);
139 if (optimize_lexical_comparison (*e))
140 gfc_simplify_expr (*e, 0);
142 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
143 gfc_simplify_expr (*e, 0);
145 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
146 switch ((*e)->value.function.isym->id)
148 case GFC_ISYM_MINLOC:
149 case GFC_ISYM_MAXLOC:
150 optimize_minmaxloc (e);
163 /* Callback function for common function elimination, called from cfe_expr_0.
164 Put all eligible function expressions into expr_array. */
167 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
168 void *data ATTRIBUTE_UNUSED)
171 if ((*e)->expr_type != EXPR_FUNCTION)
174 /* We don't do character functions with unknown charlens. */
175 if ((*e)->ts.type == BT_CHARACTER
176 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
177 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
180 /* We don't do function elimination within FORALL statements, it can
181 lead to wrong-code in certain circumstances. */
183 if (forall_level > 0)
186 /* Function elimination inside an iterator could lead to functions
187 which depend on iterator variables being moved outside. */
189 if (iterator_level > 0)
192 /* If we don't know the shape at compile time, we create an allocatable
193 temporary variable to hold the intermediate result, but only if
194 allocation on assignment is active. */
196 if ((*e)->rank > 0 && (*e)->shape == NULL && !gfc_option.flag_realloc_lhs)
199 /* Skip the test for pure functions if -faggressive-function-elimination
201 if ((*e)->value.function.esym)
203 /* Don't create an array temporary for elemental functions. */
204 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
207 /* Only eliminate potentially impure functions if the
208 user specifically requested it. */
209 if (!gfc_option.flag_aggressive_function_elimination
210 && !(*e)->value.function.esym->attr.pure
211 && !(*e)->value.function.esym->attr.implicit_pure)
215 if ((*e)->value.function.isym)
217 /* Conversions are handled on the fly by the middle end,
218 transpose during trans-* stages and TRANSFER by the middle end. */
219 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
220 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
221 || gfc_inline_intrinsic_function_p (*e))
224 /* Don't create an array temporary for elemental functions,
225 as this would be wasteful of memory.
226 FIXME: Create a scalar temporary during scalarization. */
227 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
230 if (!(*e)->value.function.isym->pure)
234 if (expr_count >= expr_size)
236 expr_size += expr_size;
237 expr_array = XRESIZEVEC(gfc_expr **, expr_array, expr_size);
239 expr_array[expr_count] = e;
244 /* Returns a new expression (a variable) to be used in place of the old one,
245 with an an assignment statement before the current statement to set
246 the value of the variable. Creates a new BLOCK for the statement if
247 that hasn't already been done and puts the statement, plus the
248 newly created variables, in that block. */
251 create_var (gfc_expr * e)
253 char name[GFC_MAX_SYMBOL_LEN +1];
255 gfc_symtree *symtree;
262 /* If the block hasn't already been created, do so. */
263 if (inserted_block == NULL)
265 inserted_block = XCNEW (gfc_code);
266 inserted_block->op = EXEC_BLOCK;
267 inserted_block->loc = (*current_code)->loc;
268 ns = gfc_build_block_ns (current_ns);
269 inserted_block->ext.block.ns = ns;
270 inserted_block->ext.block.assoc = NULL;
272 ns->code = *current_code;
274 /* If the statement has a label, make sure it is transferred to
275 the newly created block. */
277 if ((*current_code)->here)
279 inserted_block->here = (*current_code)->here;
280 (*current_code)->here = NULL;
283 inserted_block->next = (*current_code)->next;
284 changed_statement = &(inserted_block->ext.block.ns->code);
285 (*current_code)->next = NULL;
286 /* Insert the BLOCK at the right position. */
287 *current_code = inserted_block;
288 ns->parent = current_ns;
291 ns = inserted_block->ext.block.ns;
293 sprintf(name, "__var_%d",num++);
294 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
297 symbol = symtree->n.sym;
302 symbol->as = gfc_get_array_spec ();
303 symbol->as->rank = e->rank;
305 if (e->shape == NULL)
307 /* We don't know the shape at compile time, so we use an
309 symbol->as->type = AS_DEFERRED;
310 symbol->attr.allocatable = 1;
314 symbol->as->type = AS_EXPLICIT;
315 /* Copy the shape. */
316 for (i=0; i<e->rank; i++)
320 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
322 mpz_set_si (p->value.integer, 1);
323 symbol->as->lower[i] = p;
325 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
327 mpz_set (q->value.integer, e->shape[i]);
328 symbol->as->upper[i] = q;
333 symbol->attr.flavor = FL_VARIABLE;
334 symbol->attr.referenced = 1;
335 symbol->attr.dimension = e->rank > 0;
336 gfc_commit_symbol (symbol);
338 result = gfc_get_expr ();
339 result->expr_type = EXPR_VARIABLE;
341 result->rank = e->rank;
342 result->shape = gfc_copy_shape (e->shape, e->rank);
343 result->symtree = symtree;
344 result->where = e->where;
347 result->ref = gfc_get_ref ();
348 result->ref->type = REF_ARRAY;
349 result->ref->u.ar.type = AR_FULL;
350 result->ref->u.ar.where = e->where;
351 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
352 ? CLASS_DATA (symbol)->as : symbol->as;
353 if (gfc_option.warn_array_temp)
354 gfc_warning ("Creating array temporary at %L", &(e->where));
357 /* Generate the new assignment. */
358 n = XCNEW (gfc_code);
360 n->loc = (*current_code)->loc;
361 n->next = *changed_statement;
362 n->expr1 = gfc_copy_expr (result);
364 *changed_statement = n;
369 /* Warn about function elimination. */
372 warn_function_elimination (gfc_expr *e)
374 if (e->expr_type != EXPR_FUNCTION)
376 if (e->value.function.esym)
377 gfc_warning ("Removing call to function '%s' at %L",
378 e->value.function.esym->name, &(e->where));
379 else if (e->value.function.isym)
380 gfc_warning ("Removing call to function '%s' at %L",
381 e->value.function.isym->name, &(e->where));
383 /* Callback function for the code walker for doing common function
384 elimination. This builds up the list of functions in the expression
385 and goes through them to detect duplicates, which it then replaces
389 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
390 void *data ATTRIBUTE_UNUSED)
395 /* Don't do this optimization within OMP workshare. */
397 if (in_omp_workshare)
405 gfc_expr_walker (e, cfe_register_funcs, NULL);
407 /* Walk through all the functions. */
409 for (i=1; i<expr_count; i++)
411 /* Skip if the function has been replaced by a variable already. */
412 if ((*(expr_array[i]))->expr_type == EXPR_VARIABLE)
418 if (gfc_dep_compare_functions(*(expr_array[i]),
419 *(expr_array[j]), true) == 0)
422 newvar = create_var (*(expr_array[i]));
424 if (gfc_option.warn_function_elimination)
425 warn_function_elimination (*(expr_array[j]));
427 free (*(expr_array[j]));
428 *(expr_array[j]) = gfc_copy_expr (newvar);
432 *(expr_array[i]) = newvar;
435 /* We did all the necessary walking in this function. */
440 /* Callback function for common function elimination, called from
441 gfc_code_walker. This keeps track of the current code, in order
442 to insert statements as needed. */
445 cfe_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
446 void *data ATTRIBUTE_UNUSED)
449 inserted_block = NULL;
450 changed_statement = NULL;
454 /* Dummy function for expression call back, for use when we
455 really don't want to do any walking. */
458 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
459 void *data ATTRIBUTE_UNUSED)
465 /* Code callback function for converting
472 This is because common function elimination would otherwise place the
473 temporary variables outside the loop. */
476 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
477 void *data ATTRIBUTE_UNUSED)
480 gfc_code *c_if1, *c_if2, *c_exit;
482 gfc_expr *e_not, *e_cond;
484 if (co->op != EXEC_DO_WHILE)
487 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
492 /* Generate the condition of the if statement, which is .not. the original
494 e_not = gfc_get_expr ();
495 e_not->ts = e_cond->ts;
496 e_not->where = e_cond->where;
497 e_not->expr_type = EXPR_OP;
498 e_not->value.op.op = INTRINSIC_NOT;
499 e_not->value.op.op1 = e_cond;
501 /* Generate the EXIT statement. */
502 c_exit = XCNEW (gfc_code);
503 c_exit->op = EXEC_EXIT;
504 c_exit->ext.which_construct = co;
505 c_exit->loc = co->loc;
507 /* Generate the IF statement. */
508 c_if2 = XCNEW (gfc_code);
510 c_if2->expr1 = e_not;
511 c_if2->next = c_exit;
512 c_if2->loc = co->loc;
514 /* ... plus the one to chain it to. */
515 c_if1 = XCNEW (gfc_code);
517 c_if1->block = c_if2;
518 c_if1->loc = co->loc;
520 /* Make the DO WHILE loop into a DO block by replacing the condition
521 with a true constant. */
522 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
524 /* Hang the generated if statement into the loop body. */
526 loopblock = co->block->next;
527 co->block->next = c_if1;
528 c_if1->next = loopblock;
533 /* Code callback function for converting
546 because otherwise common function elimination would place the BLOCKs
547 into the wrong place. */
550 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
551 void *data ATTRIBUTE_UNUSED)
554 gfc_code *c_if1, *c_if2, *else_stmt;
556 if (co->op != EXEC_IF)
559 /* This loop starts out with the first ELSE statement. */
560 else_stmt = co->block->block;
562 while (else_stmt != NULL)
566 /* If there is no condition, we're done. */
567 if (else_stmt->expr1 == NULL)
570 next_else = else_stmt->block;
572 /* Generate the new IF statement. */
573 c_if2 = XCNEW (gfc_code);
575 c_if2->expr1 = else_stmt->expr1;
576 c_if2->next = else_stmt->next;
577 c_if2->loc = else_stmt->loc;
578 c_if2->block = next_else;
580 /* ... plus the one to chain it to. */
581 c_if1 = XCNEW (gfc_code);
583 c_if1->block = c_if2;
584 c_if1->loc = else_stmt->loc;
586 /* Insert the new IF after the ELSE. */
587 else_stmt->expr1 = NULL;
588 else_stmt->next = c_if1;
589 else_stmt->block = NULL;
591 else_stmt = next_else;
593 /* Don't walk subtrees. */
596 /* Optimize a namespace, including all contained namespaces. */
599 optimize_namespace (gfc_namespace *ns)
605 in_omp_workshare = false;
607 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
608 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
609 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
610 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
612 /* BLOCKs are handled in the expression walker below. */
613 for (ns = ns->contained; ns; ns = ns->sibling)
615 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
616 optimize_namespace (ns);
623 a = matmul(b,c) ; a = a + d
624 where the array function is not elemental and not allocatable
625 and does not depend on the left-hand side.
629 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
634 if (e->expr_type == EXPR_OP)
636 switch (e->value.op.op)
638 /* Unary operators and exponentiation: Only look at a single
641 case INTRINSIC_UPLUS:
642 case INTRINSIC_UMINUS:
643 case INTRINSIC_PARENTHESES:
644 case INTRINSIC_POWER:
645 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
650 /* Binary operators. */
651 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
654 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
660 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
661 && ! (e->value.function.esym
662 && (e->value.function.esym->attr.elemental
663 || e->value.function.esym->attr.allocatable
664 || e->value.function.esym->ts.type != c->expr1->ts.type
665 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
666 && ! (e->value.function.isym
667 && (e->value.function.isym->elemental
668 || e->ts.type != c->expr1->ts.type
669 || e->ts.kind != c->expr1->ts.kind))
670 && ! gfc_inline_intrinsic_function_p (e))
676 /* Insert a new assignment statement after the current one. */
677 n = XCNEW (gfc_code);
683 n->expr1 = gfc_copy_expr (c->expr1);
685 new_expr = gfc_copy_expr (c->expr1);
693 /* Nothing to optimize. */
697 /* Remove unneeded TRIMs at the end of expressions. */
700 remove_trim (gfc_expr *rhs)
706 /* Check for a // b // trim(c). Looping is probably not
707 necessary because the parser usually generates
708 (// (// a b ) trim(c) ) , but better safe than sorry. */
710 while (rhs->expr_type == EXPR_OP
711 && rhs->value.op.op == INTRINSIC_CONCAT)
712 rhs = rhs->value.op.op2;
714 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
715 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
717 strip_function_call (rhs);
718 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
726 /* Optimizations for an assignment. */
729 optimize_assignment (gfc_code * c)
736 /* Optimize away a = trim(b), where a is a character variable. */
738 if (lhs->ts.type == BT_CHARACTER)
741 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
742 optimize_binop_array_assignment (c, &rhs, false);
746 /* Remove an unneeded function call, modifying the expression.
747 This replaces the function call with the value of its
748 first argument. The rest of the argument list is freed. */
751 strip_function_call (gfc_expr *e)
754 gfc_actual_arglist *a;
756 a = e->value.function.actual;
758 /* We should have at least one argument. */
759 gcc_assert (a->expr != NULL);
763 /* Free the remaining arglist, if any. */
765 gfc_free_actual_arglist (a->next);
767 /* Graft the argument expression onto the original function. */
773 /* Optimization of lexical comparison functions. */
776 optimize_lexical_comparison (gfc_expr *e)
778 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
781 switch (e->value.function.isym->id)
784 return optimize_comparison (e, INTRINSIC_LE);
787 return optimize_comparison (e, INTRINSIC_GE);
790 return optimize_comparison (e, INTRINSIC_GT);
793 return optimize_comparison (e, INTRINSIC_LT);
801 /* Recursive optimization of operators. */
804 optimize_op (gfc_expr *e)
806 gfc_intrinsic_op op = e->value.op.op;
811 case INTRINSIC_EQ_OS:
813 case INTRINSIC_GE_OS:
815 case INTRINSIC_LE_OS:
817 case INTRINSIC_NE_OS:
819 case INTRINSIC_GT_OS:
821 case INTRINSIC_LT_OS:
822 return optimize_comparison (e, op);
831 /* Optimize expressions for equality. */
834 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
840 gfc_actual_arglist *firstarg, *secondarg;
842 if (e->expr_type == EXPR_OP)
846 op1 = e->value.op.op1;
847 op2 = e->value.op.op2;
849 else if (e->expr_type == EXPR_FUNCTION)
851 /* One of the lexical comparision functions. */
852 firstarg = e->value.function.actual;
853 secondarg = firstarg->next;
854 op1 = firstarg->expr;
855 op2 = secondarg->expr;
860 /* Strip off unneeded TRIM calls from string comparisons. */
862 change = remove_trim (op1);
864 if (remove_trim (op2))
867 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
868 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
869 handles them well). However, there are also cases that need a non-scalar
870 argument. For example the any intrinsic. See PR 45380. */
874 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
876 if (flag_finite_math_only
877 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
878 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
880 eq = gfc_dep_compare_expr (op1, op2);
883 /* Replace A // B < A // C with B < C, and A // B < C // B
885 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
886 && op1->expr_type == EXPR_OP
887 && op1->value.op.op == INTRINSIC_CONCAT
888 && op2->expr_type == EXPR_OP
889 && op2->value.op.op == INTRINSIC_CONCAT)
891 gfc_expr *op1_left = op1->value.op.op1;
892 gfc_expr *op2_left = op2->value.op.op1;
893 gfc_expr *op1_right = op1->value.op.op2;
894 gfc_expr *op2_right = op2->value.op.op2;
896 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
898 /* Watch out for 'A ' // x vs. 'A' // x. */
900 if (op1_left->expr_type == EXPR_CONSTANT
901 && op2_left->expr_type == EXPR_CONSTANT
902 && op1_left->value.character.length
903 != op2_left->value.character.length)
911 firstarg->expr = op1_right;
912 secondarg->expr = op2_right;
916 e->value.op.op1 = op1_right;
917 e->value.op.op2 = op2_right;
919 optimize_comparison (e, op);
923 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
929 firstarg->expr = op1_left;
930 secondarg->expr = op2_left;
934 e->value.op.op1 = op1_left;
935 e->value.op.op2 = op2_left;
938 optimize_comparison (e, op);
945 /* eq can only be -1, 0 or 1 at this point. */
949 case INTRINSIC_EQ_OS:
954 case INTRINSIC_GE_OS:
959 case INTRINSIC_LE_OS:
964 case INTRINSIC_NE_OS:
969 case INTRINSIC_GT_OS:
974 case INTRINSIC_LT_OS:
979 gfc_internal_error ("illegal OP in optimize_comparison");
983 /* Replace the expression by a constant expression. The typespec
984 and where remains the way it is. */
987 e->expr_type = EXPR_CONSTANT;
988 e->value.logical = result;
996 /* Optimize a trim function by replacing it with an equivalent substring
997 involving a call to len_trim. This only works for expressions where
998 variables are trimmed. Return true if anything was modified. */
1001 optimize_trim (gfc_expr *e)
1006 gfc_actual_arglist *actual_arglist, *next;
1007 gfc_ref **rr = NULL;
1009 /* Don't do this optimization within an argument list, because
1010 otherwise aliasing issues may occur. */
1012 if (count_arglist != 1)
1015 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
1016 || e->value.function.isym == NULL
1017 || e->value.function.isym->id != GFC_ISYM_TRIM)
1020 a = e->value.function.actual->expr;
1022 if (a->expr_type != EXPR_VARIABLE)
1025 /* Follow all references to find the correct place to put the newly
1026 created reference. FIXME: Also handle substring references and
1027 array references. Array references cause strange regressions at
1032 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
1034 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
1039 strip_function_call (e);
1044 /* Create the reference. */
1046 ref = gfc_get_ref ();
1047 ref->type = REF_SUBSTRING;
1049 /* Set the start of the reference. */
1051 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1053 /* Build the function call to len_trim(x, gfc_defaul_integer_kind). */
1055 fcn = gfc_get_expr ();
1056 fcn->expr_type = EXPR_FUNCTION;
1057 fcn->value.function.isym =
1058 gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1059 actual_arglist = gfc_get_actual_arglist ();
1060 actual_arglist->expr = gfc_copy_expr (e);
1061 next = gfc_get_actual_arglist ();
1062 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL,
1063 gfc_default_integer_kind);
1064 actual_arglist->next = next;
1065 fcn->value.function.actual = actual_arglist;
1067 /* Set the end of the reference to the call to len_trim. */
1069 ref->u.ss.end = fcn;
1070 gcc_assert (*rr == NULL);
1075 /* Optimize minloc(b), where b is rank 1 array, into
1076 (/ minloc(b, dim=1) /), and similarly for maxloc,
1077 as the latter forms are expanded inline. */
1080 optimize_minmaxloc (gfc_expr **e)
1083 gfc_actual_arglist *a;
1087 || fn->value.function.actual == NULL
1088 || fn->value.function.actual->expr == NULL
1089 || fn->value.function.actual->expr->rank != 1)
1092 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
1093 (*e)->shape = fn->shape;
1096 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
1098 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
1099 strcpy (name, fn->value.function.name);
1100 p = strstr (name, "loc0");
1102 fn->value.function.name = gfc_get_string (name);
1103 if (fn->value.function.actual->next)
1105 a = fn->value.function.actual->next;
1106 gcc_assert (a->expr == NULL);
1110 a = gfc_get_actual_arglist ();
1111 fn->value.function.actual->next = a;
1113 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
1115 mpz_set_ui (a->expr->value.integer, 1);
1118 #define WALK_SUBEXPR(NODE) \
1121 result = gfc_expr_walker (&(NODE), exprfn, data); \
1126 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
1128 /* Walk expression *E, calling EXPRFN on each expression in it. */
1131 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
1135 int walk_subtrees = 1;
1136 gfc_actual_arglist *a;
1140 int result = exprfn (e, &walk_subtrees, data);
1144 switch ((*e)->expr_type)
1147 WALK_SUBEXPR ((*e)->value.op.op1);
1148 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
1151 for (a = (*e)->value.function.actual; a; a = a->next)
1152 WALK_SUBEXPR (a->expr);
1156 WALK_SUBEXPR ((*e)->value.compcall.base_object);
1157 for (a = (*e)->value.compcall.actual; a; a = a->next)
1158 WALK_SUBEXPR (a->expr);
1161 case EXPR_STRUCTURE:
1163 for (c = gfc_constructor_first ((*e)->value.constructor); c;
1164 c = gfc_constructor_next (c))
1166 if (c->iterator == NULL)
1167 WALK_SUBEXPR (c->expr);
1171 WALK_SUBEXPR (c->expr);
1173 WALK_SUBEXPR (c->iterator->var);
1174 WALK_SUBEXPR (c->iterator->start);
1175 WALK_SUBEXPR (c->iterator->end);
1176 WALK_SUBEXPR (c->iterator->step);
1180 if ((*e)->expr_type != EXPR_ARRAY)
1183 /* Fall through to the variable case in order to walk the
1186 case EXPR_SUBSTRING:
1188 for (r = (*e)->ref; r; r = r->next)
1197 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
1199 for (i=0; i< ar->dimen; i++)
1201 WALK_SUBEXPR (ar->start[i]);
1202 WALK_SUBEXPR (ar->end[i]);
1203 WALK_SUBEXPR (ar->stride[i]);
1210 WALK_SUBEXPR (r->u.ss.start);
1211 WALK_SUBEXPR (r->u.ss.end);
1227 #define WALK_SUBCODE(NODE) \
1230 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
1236 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
1237 on each expression in it. If any of the hooks returns non-zero, that
1238 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
1239 no subcodes or subexpressions are traversed. */
1242 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
1245 for (; *c; c = &(*c)->next)
1247 int walk_subtrees = 1;
1248 int result = codefn (c, &walk_subtrees, data);
1255 gfc_actual_arglist *a;
1257 gfc_association_list *alist;
1258 bool saved_in_omp_workshare;
1260 /* There might be statement insertions before the current code,
1261 which must not affect the expression walker. */
1264 saved_in_omp_workshare = in_omp_workshare;
1270 WALK_SUBCODE (co->ext.block.ns->code);
1271 for (alist = co->ext.block.assoc; alist; alist = alist->next)
1272 WALK_SUBEXPR (alist->target);
1276 WALK_SUBEXPR (co->ext.iterator->var);
1277 WALK_SUBEXPR (co->ext.iterator->start);
1278 WALK_SUBEXPR (co->ext.iterator->end);
1279 WALK_SUBEXPR (co->ext.iterator->step);
1283 case EXEC_ASSIGN_CALL:
1284 for (a = co->ext.actual; a; a = a->next)
1285 WALK_SUBEXPR (a->expr);
1289 WALK_SUBEXPR (co->expr1);
1290 for (a = co->ext.actual; a; a = a->next)
1291 WALK_SUBEXPR (a->expr);
1295 WALK_SUBEXPR (co->expr1);
1296 for (b = co->block; b; b = b->block)
1299 for (cp = b->ext.block.case_list; cp; cp = cp->next)
1301 WALK_SUBEXPR (cp->low);
1302 WALK_SUBEXPR (cp->high);
1304 WALK_SUBCODE (b->next);
1309 case EXEC_DEALLOCATE:
1312 for (a = co->ext.alloc.list; a; a = a->next)
1313 WALK_SUBEXPR (a->expr);
1318 case EXEC_DO_CONCURRENT:
1320 gfc_forall_iterator *fa;
1321 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
1323 WALK_SUBEXPR (fa->var);
1324 WALK_SUBEXPR (fa->start);
1325 WALK_SUBEXPR (fa->end);
1326 WALK_SUBEXPR (fa->stride);
1328 if (co->op == EXEC_FORALL)
1334 WALK_SUBEXPR (co->ext.open->unit);
1335 WALK_SUBEXPR (co->ext.open->file);
1336 WALK_SUBEXPR (co->ext.open->status);
1337 WALK_SUBEXPR (co->ext.open->access);
1338 WALK_SUBEXPR (co->ext.open->form);
1339 WALK_SUBEXPR (co->ext.open->recl);
1340 WALK_SUBEXPR (co->ext.open->blank);
1341 WALK_SUBEXPR (co->ext.open->position);
1342 WALK_SUBEXPR (co->ext.open->action);
1343 WALK_SUBEXPR (co->ext.open->delim);
1344 WALK_SUBEXPR (co->ext.open->pad);
1345 WALK_SUBEXPR (co->ext.open->iostat);
1346 WALK_SUBEXPR (co->ext.open->iomsg);
1347 WALK_SUBEXPR (co->ext.open->convert);
1348 WALK_SUBEXPR (co->ext.open->decimal);
1349 WALK_SUBEXPR (co->ext.open->encoding);
1350 WALK_SUBEXPR (co->ext.open->round);
1351 WALK_SUBEXPR (co->ext.open->sign);
1352 WALK_SUBEXPR (co->ext.open->asynchronous);
1353 WALK_SUBEXPR (co->ext.open->id);
1354 WALK_SUBEXPR (co->ext.open->newunit);
1358 WALK_SUBEXPR (co->ext.close->unit);
1359 WALK_SUBEXPR (co->ext.close->status);
1360 WALK_SUBEXPR (co->ext.close->iostat);
1361 WALK_SUBEXPR (co->ext.close->iomsg);
1364 case EXEC_BACKSPACE:
1368 WALK_SUBEXPR (co->ext.filepos->unit);
1369 WALK_SUBEXPR (co->ext.filepos->iostat);
1370 WALK_SUBEXPR (co->ext.filepos->iomsg);
1374 WALK_SUBEXPR (co->ext.inquire->unit);
1375 WALK_SUBEXPR (co->ext.inquire->file);
1376 WALK_SUBEXPR (co->ext.inquire->iomsg);
1377 WALK_SUBEXPR (co->ext.inquire->iostat);
1378 WALK_SUBEXPR (co->ext.inquire->exist);
1379 WALK_SUBEXPR (co->ext.inquire->opened);
1380 WALK_SUBEXPR (co->ext.inquire->number);
1381 WALK_SUBEXPR (co->ext.inquire->named);
1382 WALK_SUBEXPR (co->ext.inquire->name);
1383 WALK_SUBEXPR (co->ext.inquire->access);
1384 WALK_SUBEXPR (co->ext.inquire->sequential);
1385 WALK_SUBEXPR (co->ext.inquire->direct);
1386 WALK_SUBEXPR (co->ext.inquire->form);
1387 WALK_SUBEXPR (co->ext.inquire->formatted);
1388 WALK_SUBEXPR (co->ext.inquire->unformatted);
1389 WALK_SUBEXPR (co->ext.inquire->recl);
1390 WALK_SUBEXPR (co->ext.inquire->nextrec);
1391 WALK_SUBEXPR (co->ext.inquire->blank);
1392 WALK_SUBEXPR (co->ext.inquire->position);
1393 WALK_SUBEXPR (co->ext.inquire->action);
1394 WALK_SUBEXPR (co->ext.inquire->read);
1395 WALK_SUBEXPR (co->ext.inquire->write);
1396 WALK_SUBEXPR (co->ext.inquire->readwrite);
1397 WALK_SUBEXPR (co->ext.inquire->delim);
1398 WALK_SUBEXPR (co->ext.inquire->encoding);
1399 WALK_SUBEXPR (co->ext.inquire->pad);
1400 WALK_SUBEXPR (co->ext.inquire->iolength);
1401 WALK_SUBEXPR (co->ext.inquire->convert);
1402 WALK_SUBEXPR (co->ext.inquire->strm_pos);
1403 WALK_SUBEXPR (co->ext.inquire->asynchronous);
1404 WALK_SUBEXPR (co->ext.inquire->decimal);
1405 WALK_SUBEXPR (co->ext.inquire->pending);
1406 WALK_SUBEXPR (co->ext.inquire->id);
1407 WALK_SUBEXPR (co->ext.inquire->sign);
1408 WALK_SUBEXPR (co->ext.inquire->size);
1409 WALK_SUBEXPR (co->ext.inquire->round);
1413 WALK_SUBEXPR (co->ext.wait->unit);
1414 WALK_SUBEXPR (co->ext.wait->iostat);
1415 WALK_SUBEXPR (co->ext.wait->iomsg);
1416 WALK_SUBEXPR (co->ext.wait->id);
1421 WALK_SUBEXPR (co->ext.dt->io_unit);
1422 WALK_SUBEXPR (co->ext.dt->format_expr);
1423 WALK_SUBEXPR (co->ext.dt->rec);
1424 WALK_SUBEXPR (co->ext.dt->advance);
1425 WALK_SUBEXPR (co->ext.dt->iostat);
1426 WALK_SUBEXPR (co->ext.dt->size);
1427 WALK_SUBEXPR (co->ext.dt->iomsg);
1428 WALK_SUBEXPR (co->ext.dt->id);
1429 WALK_SUBEXPR (co->ext.dt->pos);
1430 WALK_SUBEXPR (co->ext.dt->asynchronous);
1431 WALK_SUBEXPR (co->ext.dt->blank);
1432 WALK_SUBEXPR (co->ext.dt->decimal);
1433 WALK_SUBEXPR (co->ext.dt->delim);
1434 WALK_SUBEXPR (co->ext.dt->pad);
1435 WALK_SUBEXPR (co->ext.dt->round);
1436 WALK_SUBEXPR (co->ext.dt->sign);
1437 WALK_SUBEXPR (co->ext.dt->extra_comma);
1440 case EXEC_OMP_PARALLEL:
1441 case EXEC_OMP_PARALLEL_DO:
1442 case EXEC_OMP_PARALLEL_SECTIONS:
1444 in_omp_workshare = false;
1446 /* This goto serves as a shortcut to avoid code
1447 duplication or a larger if or switch statement. */
1448 goto check_omp_clauses;
1450 case EXEC_OMP_WORKSHARE:
1451 case EXEC_OMP_PARALLEL_WORKSHARE:
1453 in_omp_workshare = true;
1458 case EXEC_OMP_SECTIONS:
1459 case EXEC_OMP_SINGLE:
1460 case EXEC_OMP_END_SINGLE:
1463 /* Come to this label only from the
1464 EXEC_OMP_PARALLEL_* cases above. */
1468 if (co->ext.omp_clauses)
1470 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
1471 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
1472 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
1473 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
1480 WALK_SUBEXPR (co->expr1);
1481 WALK_SUBEXPR (co->expr2);
1482 WALK_SUBEXPR (co->expr3);
1483 WALK_SUBEXPR (co->expr4);
1484 for (b = co->block; b; b = b->block)
1486 WALK_SUBEXPR (b->expr1);
1487 WALK_SUBEXPR (b->expr2);
1488 WALK_SUBCODE (b->next);
1491 if (co->op == EXEC_FORALL)
1494 in_omp_workshare = saved_in_omp_workshare;