* tree-loop-distribution.c (struct partition): New field recording
[official-gcc.git] / gcc / fortran / frontend-passes.c
blob11c750352104ab468600c96536953508f8e7453e
1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2017 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 "coretypes.h"
24 #include "options.h"
25 #include "gfortran.h"
26 #include "dependency.h"
27 #include "constructor.h"
28 #include "intrinsic.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 **);
40 static bool is_empty_string (gfc_expr *e);
41 static void doloop_warn (gfc_namespace *);
42 static void optimize_reduction (gfc_namespace *);
43 static int callback_reduction (gfc_expr **, int *, void *);
44 static void realloc_strings (gfc_namespace *);
45 static gfc_expr *create_var (gfc_expr *, const char *vname=NULL);
46 static int matmul_to_var_expr (gfc_expr **, int *, void *);
47 static int matmul_to_var_code (gfc_code **, int *, void *);
48 static int inline_matmul_assign (gfc_code **, int *, void *);
49 static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *,
50 locus *, gfc_namespace *,
51 char *vname=NULL);
52 static gfc_expr* check_conjg_transpose_variable (gfc_expr *, bool *,
53 bool *);
54 static bool has_dimen_vector_ref (gfc_expr *);
55 static int matmul_temp_args (gfc_code **, int *,void *data);
57 #ifdef CHECKING_P
58 static void check_locus (gfc_namespace *);
59 #endif
61 /* How deep we are inside an argument list. */
63 static int count_arglist;
65 /* Vector of gfc_expr ** we operate on. */
67 static vec<gfc_expr **> expr_array;
69 /* Pointer to the gfc_code we currently work on - to be able to insert
70 a block before the statement. */
72 static gfc_code **current_code;
74 /* Pointer to the block to be inserted, and the statement we are
75 changing within the block. */
77 static gfc_code *inserted_block, **changed_statement;
79 /* The namespace we are currently dealing with. */
81 static gfc_namespace *current_ns;
83 /* If we are within any forall loop. */
85 static int forall_level;
87 /* Keep track of whether we are within an OMP workshare. */
89 static bool in_omp_workshare;
91 /* Keep track of whether we are within a WHERE statement. */
93 static bool in_where;
95 /* Keep track of iterators for array constructors. */
97 static int iterator_level;
99 /* Keep track of DO loop levels. */
101 static vec<gfc_code *> doloop_list;
103 static int doloop_level;
105 /* Vector of gfc_expr * to keep track of DO loops. */
107 struct my_struct *evec;
109 /* Keep track of association lists. */
111 static bool in_assoc_list;
113 /* Counter for temporary variables. */
115 static int var_num = 1;
117 /* What sort of matrix we are dealing with when inlining MATMUL. */
119 enum matrix_case { none=0, A2B2, A2B1, A1B2, A2B2T, A2TB2 };
121 /* Keep track of the number of expressions we have inserted so far
122 using create_var. */
124 int n_vars;
126 /* Entry point - run all passes for a namespace. */
128 void
129 gfc_run_passes (gfc_namespace *ns)
132 /* Warn about dubious DO loops where the index might
133 change. */
135 doloop_level = 0;
136 doloop_warn (ns);
137 doloop_list.release ();
138 int w, e;
140 #ifdef CHECKING_P
141 check_locus (ns);
142 #endif
144 if (flag_frontend_optimize)
146 optimize_namespace (ns);
147 optimize_reduction (ns);
148 if (flag_dump_fortran_optimized)
149 gfc_dump_parse_tree (ns, stdout);
151 expr_array.release ();
154 gfc_get_errors (&w, &e);
155 if (e > 0)
156 return;
158 if (flag_realloc_lhs)
159 realloc_strings (ns);
162 #ifdef CHECKING_P
164 /* Callback function: Warn if there is no location information in a
165 statement. */
167 static int
168 check_locus_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
169 void *data ATTRIBUTE_UNUSED)
171 current_code = c;
172 if (c && *c && (((*c)->loc.nextc == NULL) || ((*c)->loc.lb == NULL)))
173 gfc_warning_internal (0, "No location in statement");
175 return 0;
179 /* Callback function: Warn if there is no location information in an
180 expression. */
182 static int
183 check_locus_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
184 void *data ATTRIBUTE_UNUSED)
187 if (e && *e && (((*e)->where.nextc == NULL || (*e)->where.lb == NULL)))
188 gfc_warning_internal (0, "No location in expression near %L",
189 &((*current_code)->loc));
190 return 0;
193 /* Run check for missing location information. */
195 static void
196 check_locus (gfc_namespace *ns)
198 gfc_code_walker (&ns->code, check_locus_code, check_locus_expr, NULL);
200 for (ns = ns->contained; ns; ns = ns->sibling)
202 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
203 check_locus (ns);
207 #endif
209 /* Callback for each gfc_code node invoked from check_realloc_strings.
210 For an allocatable LHS string which also appears as a variable on
211 the RHS, replace
213 a = a(x:y)
215 with
217 tmp = a(x:y)
218 a = tmp
221 static int
222 realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
223 void *data ATTRIBUTE_UNUSED)
225 gfc_expr *expr1, *expr2;
226 gfc_code *co = *c;
227 gfc_expr *n;
228 gfc_ref *ref;
229 bool found_substr;
231 if (co->op != EXEC_ASSIGN)
232 return 0;
234 expr1 = co->expr1;
235 if (expr1->ts.type != BT_CHARACTER || expr1->rank != 0
236 || !gfc_expr_attr(expr1).allocatable
237 || !expr1->ts.deferred)
238 return 0;
240 expr2 = gfc_discard_nops (co->expr2);
241 if (expr2->expr_type != EXPR_VARIABLE)
242 return 0;
244 found_substr = false;
245 for (ref = expr2->ref; ref; ref = ref->next)
247 if (ref->type == REF_SUBSTRING)
249 found_substr = true;
250 break;
253 if (!found_substr)
254 return 0;
256 if (!gfc_check_dependency (expr1, expr2, true))
257 return 0;
259 /* gfc_check_dependency doesn't always pick up identical expressions.
260 However, eliminating the above sends the compiler into an infinite
261 loop on valid expressions. Without this check, the gimplifier emits
262 an ICE for a = a, where a is deferred character length. */
263 if (!gfc_dep_compare_expr (expr1, expr2))
264 return 0;
266 current_code = c;
267 inserted_block = NULL;
268 changed_statement = NULL;
269 n = create_var (expr2, "realloc_string");
270 co->expr2 = n;
271 return 0;
274 /* Callback for each gfc_code node invoked through gfc_code_walker
275 from optimize_namespace. */
277 static int
278 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
279 void *data ATTRIBUTE_UNUSED)
282 gfc_exec_op op;
284 op = (*c)->op;
286 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
287 || op == EXEC_CALL_PPC)
288 count_arglist = 1;
289 else
290 count_arglist = 0;
292 current_code = c;
293 inserted_block = NULL;
294 changed_statement = NULL;
296 if (op == EXEC_ASSIGN)
297 optimize_assignment (*c);
298 return 0;
301 /* Callback for each gfc_expr node invoked through gfc_code_walker
302 from optimize_namespace. */
304 static int
305 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
306 void *data ATTRIBUTE_UNUSED)
308 bool function_expr;
310 if ((*e)->expr_type == EXPR_FUNCTION)
312 count_arglist ++;
313 function_expr = true;
315 else
316 function_expr = false;
318 if (optimize_trim (*e))
319 gfc_simplify_expr (*e, 0);
321 if (optimize_lexical_comparison (*e))
322 gfc_simplify_expr (*e, 0);
324 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
325 gfc_simplify_expr (*e, 0);
327 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
328 switch ((*e)->value.function.isym->id)
330 case GFC_ISYM_MINLOC:
331 case GFC_ISYM_MAXLOC:
332 optimize_minmaxloc (e);
333 break;
334 default:
335 break;
338 if (function_expr)
339 count_arglist --;
341 return 0;
344 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
345 function is a scalar, just copy it; otherwise returns the new element, the
346 old one can be freed. */
348 static gfc_expr *
349 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
351 gfc_expr *fcn, *e = c->expr;
353 fcn = gfc_copy_expr (e);
354 if (c->iterator)
356 gfc_constructor_base newbase;
357 gfc_expr *new_expr;
358 gfc_constructor *new_c;
360 newbase = NULL;
361 new_expr = gfc_get_expr ();
362 new_expr->expr_type = EXPR_ARRAY;
363 new_expr->ts = e->ts;
364 new_expr->where = e->where;
365 new_expr->rank = 1;
366 new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
367 new_c->iterator = c->iterator;
368 new_expr->value.constructor = newbase;
369 c->iterator = NULL;
371 fcn = new_expr;
374 if (fcn->rank != 0)
376 gfc_isym_id id = fn->value.function.isym->id;
378 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
379 fcn = gfc_build_intrinsic_call (current_ns, id,
380 fn->value.function.isym->name,
381 fn->where, 3, fcn, NULL, NULL);
382 else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
383 fcn = gfc_build_intrinsic_call (current_ns, id,
384 fn->value.function.isym->name,
385 fn->where, 2, fcn, NULL);
386 else
387 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
389 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
392 return fcn;
395 /* Callback function for optimzation of reductions to scalars. Transform ANY
396 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
397 correspondingly. Handly only the simple cases without MASK and DIM. */
399 static int
400 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
401 void *data ATTRIBUTE_UNUSED)
403 gfc_expr *fn, *arg;
404 gfc_intrinsic_op op;
405 gfc_isym_id id;
406 gfc_actual_arglist *a;
407 gfc_actual_arglist *dim;
408 gfc_constructor *c;
409 gfc_expr *res, *new_expr;
410 gfc_actual_arglist *mask;
412 fn = *e;
414 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
415 || fn->value.function.isym == NULL)
416 return 0;
418 id = fn->value.function.isym->id;
420 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
421 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
422 return 0;
424 a = fn->value.function.actual;
426 /* Don't handle MASK or DIM. */
428 dim = a->next;
430 if (dim->expr != NULL)
431 return 0;
433 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
435 mask = dim->next;
436 if ( mask->expr != NULL)
437 return 0;
440 arg = a->expr;
442 if (arg->expr_type != EXPR_ARRAY)
443 return 0;
445 switch (id)
447 case GFC_ISYM_SUM:
448 op = INTRINSIC_PLUS;
449 break;
451 case GFC_ISYM_PRODUCT:
452 op = INTRINSIC_TIMES;
453 break;
455 case GFC_ISYM_ANY:
456 op = INTRINSIC_OR;
457 break;
459 case GFC_ISYM_ALL:
460 op = INTRINSIC_AND;
461 break;
463 default:
464 return 0;
467 c = gfc_constructor_first (arg->value.constructor);
469 /* Don't do any simplififcation if we have
470 - no element in the constructor or
471 - only have a single element in the array which contains an
472 iterator. */
474 if (c == NULL)
475 return 0;
477 res = copy_walk_reduction_arg (c, fn);
479 c = gfc_constructor_next (c);
480 while (c)
482 new_expr = gfc_get_expr ();
483 new_expr->ts = fn->ts;
484 new_expr->expr_type = EXPR_OP;
485 new_expr->rank = fn->rank;
486 new_expr->where = fn->where;
487 new_expr->value.op.op = op;
488 new_expr->value.op.op1 = res;
489 new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
490 res = new_expr;
491 c = gfc_constructor_next (c);
494 gfc_simplify_expr (res, 0);
495 *e = res;
496 gfc_free_expr (fn);
498 return 0;
501 /* Callback function for common function elimination, called from cfe_expr_0.
502 Put all eligible function expressions into expr_array. */
504 static int
505 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
506 void *data ATTRIBUTE_UNUSED)
509 if ((*e)->expr_type != EXPR_FUNCTION)
510 return 0;
512 /* We don't do character functions with unknown charlens. */
513 if ((*e)->ts.type == BT_CHARACTER
514 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
515 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
516 return 0;
518 /* We don't do function elimination within FORALL statements, it can
519 lead to wrong-code in certain circumstances. */
521 if (forall_level > 0)
522 return 0;
524 /* Function elimination inside an iterator could lead to functions which
525 depend on iterator variables being moved outside. FIXME: We should check
526 if the functions do indeed depend on the iterator variable. */
528 if (iterator_level > 0)
529 return 0;
531 /* If we don't know the shape at compile time, we create an allocatable
532 temporary variable to hold the intermediate result, but only if
533 allocation on assignment is active. */
535 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
536 return 0;
538 /* Skip the test for pure functions if -faggressive-function-elimination
539 is specified. */
540 if ((*e)->value.function.esym)
542 /* Don't create an array temporary for elemental functions. */
543 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
544 return 0;
546 /* Only eliminate potentially impure functions if the
547 user specifically requested it. */
548 if (!flag_aggressive_function_elimination
549 && !(*e)->value.function.esym->attr.pure
550 && !(*e)->value.function.esym->attr.implicit_pure)
551 return 0;
554 if ((*e)->value.function.isym)
556 /* Conversions are handled on the fly by the middle end,
557 transpose during trans-* stages and TRANSFER by the middle end. */
558 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
559 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
560 || gfc_inline_intrinsic_function_p (*e))
561 return 0;
563 /* Don't create an array temporary for elemental functions,
564 as this would be wasteful of memory.
565 FIXME: Create a scalar temporary during scalarization. */
566 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
567 return 0;
569 if (!(*e)->value.function.isym->pure)
570 return 0;
573 expr_array.safe_push (e);
574 return 0;
577 /* Auxiliary function to check if an expression is a temporary created by
578 create var. */
580 static bool
581 is_fe_temp (gfc_expr *e)
583 if (e->expr_type != EXPR_VARIABLE)
584 return false;
586 return e->symtree->n.sym->attr.fe_temp;
589 /* Determine the length of a string, if it can be evaluated as a constant
590 expression. Return a newly allocated gfc_expr or NULL on failure.
591 If the user specified a substring which is potentially longer than
592 the string itself, the string will be padded with spaces, which
593 is harmless. */
595 static gfc_expr *
596 constant_string_length (gfc_expr *e)
599 gfc_expr *length;
600 gfc_ref *ref;
601 gfc_expr *res;
602 mpz_t value;
604 if (e->ts.u.cl)
606 length = e->ts.u.cl->length;
607 if (length && length->expr_type == EXPR_CONSTANT)
608 return gfc_copy_expr(length);
611 /* Return length of substring, if constant. */
612 for (ref = e->ref; ref; ref = ref->next)
614 if (ref->type == REF_SUBSTRING
615 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
617 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
618 &e->where);
620 mpz_add_ui (res->value.integer, value, 1);
621 mpz_clear (value);
622 return res;
626 /* Return length of char symbol, if constant. */
628 if (e->symtree->n.sym->ts.u.cl && e->symtree->n.sym->ts.u.cl->length
629 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
630 return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length);
632 return NULL;
636 /* Insert a block at the current position unless it has already
637 been inserted; in this case use the one already there. */
639 static gfc_namespace*
640 insert_block ()
642 gfc_namespace *ns;
644 /* If the block hasn't already been created, do so. */
645 if (inserted_block == NULL)
647 inserted_block = XCNEW (gfc_code);
648 inserted_block->op = EXEC_BLOCK;
649 inserted_block->loc = (*current_code)->loc;
650 ns = gfc_build_block_ns (current_ns);
651 inserted_block->ext.block.ns = ns;
652 inserted_block->ext.block.assoc = NULL;
654 ns->code = *current_code;
656 /* If the statement has a label, make sure it is transferred to
657 the newly created block. */
659 if ((*current_code)->here)
661 inserted_block->here = (*current_code)->here;
662 (*current_code)->here = NULL;
665 inserted_block->next = (*current_code)->next;
666 changed_statement = &(inserted_block->ext.block.ns->code);
667 (*current_code)->next = NULL;
668 /* Insert the BLOCK at the right position. */
669 *current_code = inserted_block;
670 ns->parent = current_ns;
672 else
673 ns = inserted_block->ext.block.ns;
675 return ns;
678 /* Returns a new expression (a variable) to be used in place of the old one,
679 with an optional assignment statement before the current statement to set
680 the value of the variable. Creates a new BLOCK for the statement if that
681 hasn't already been done and puts the statement, plus the newly created
682 variables, in that block. Special cases: If the expression is constant or
683 a temporary which has already been created, just copy it. */
685 static gfc_expr*
686 create_var (gfc_expr * e, const char *vname)
688 char name[GFC_MAX_SYMBOL_LEN +1];
689 gfc_symtree *symtree;
690 gfc_symbol *symbol;
691 gfc_expr *result;
692 gfc_code *n;
693 gfc_namespace *ns;
694 int i;
695 bool deferred;
697 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
698 return gfc_copy_expr (e);
700 ns = insert_block ();
702 if (vname)
703 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d_%s", var_num++, vname);
704 else
705 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d", var_num++);
707 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
708 gcc_unreachable ();
710 symbol = symtree->n.sym;
711 symbol->ts = e->ts;
713 if (e->rank > 0)
715 symbol->as = gfc_get_array_spec ();
716 symbol->as->rank = e->rank;
718 if (e->shape == NULL)
720 /* We don't know the shape at compile time, so we use an
721 allocatable. */
722 symbol->as->type = AS_DEFERRED;
723 symbol->attr.allocatable = 1;
725 else
727 symbol->as->type = AS_EXPLICIT;
728 /* Copy the shape. */
729 for (i=0; i<e->rank; i++)
731 gfc_expr *p, *q;
733 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
734 &(e->where));
735 mpz_set_si (p->value.integer, 1);
736 symbol->as->lower[i] = p;
738 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
739 &(e->where));
740 mpz_set (q->value.integer, e->shape[i]);
741 symbol->as->upper[i] = q;
746 deferred = 0;
747 if (e->ts.type == BT_CHARACTER && e->rank == 0)
749 gfc_expr *length;
751 symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
752 length = constant_string_length (e);
753 if (length)
754 symbol->ts.u.cl->length = length;
755 else
757 symbol->attr.allocatable = 1;
758 deferred = 1;
762 symbol->attr.flavor = FL_VARIABLE;
763 symbol->attr.referenced = 1;
764 symbol->attr.dimension = e->rank > 0;
765 symbol->attr.fe_temp = 1;
766 gfc_commit_symbol (symbol);
768 result = gfc_get_expr ();
769 result->expr_type = EXPR_VARIABLE;
770 result->ts = e->ts;
771 result->ts.deferred = deferred;
772 result->rank = e->rank;
773 result->shape = gfc_copy_shape (e->shape, e->rank);
774 result->symtree = symtree;
775 result->where = e->where;
776 if (e->rank > 0)
778 result->ref = gfc_get_ref ();
779 result->ref->type = REF_ARRAY;
780 result->ref->u.ar.type = AR_FULL;
781 result->ref->u.ar.where = e->where;
782 result->ref->u.ar.dimen = e->rank;
783 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
784 ? CLASS_DATA (symbol)->as : symbol->as;
785 if (warn_array_temporaries)
786 gfc_warning (OPT_Warray_temporaries,
787 "Creating array temporary at %L", &(e->where));
790 /* Generate the new assignment. */
791 n = XCNEW (gfc_code);
792 n->op = EXEC_ASSIGN;
793 n->loc = (*current_code)->loc;
794 n->next = *changed_statement;
795 n->expr1 = gfc_copy_expr (result);
796 n->expr2 = e;
797 *changed_statement = n;
798 n_vars ++;
800 return result;
803 /* Warn about function elimination. */
805 static void
806 do_warn_function_elimination (gfc_expr *e)
808 if (e->expr_type != EXPR_FUNCTION)
809 return;
810 if (e->value.function.esym)
811 gfc_warning (OPT_Wfunction_elimination,
812 "Removing call to function %qs at %L",
813 e->value.function.esym->name, &(e->where));
814 else if (e->value.function.isym)
815 gfc_warning (OPT_Wfunction_elimination,
816 "Removing call to function %qs at %L",
817 e->value.function.isym->name, &(e->where));
819 /* Callback function for the code walker for doing common function
820 elimination. This builds up the list of functions in the expression
821 and goes through them to detect duplicates, which it then replaces
822 by variables. */
824 static int
825 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
826 void *data ATTRIBUTE_UNUSED)
828 int i,j;
829 gfc_expr *newvar;
830 gfc_expr **ei, **ej;
832 /* Don't do this optimization within OMP workshare or ASSOC lists. */
834 if (in_omp_workshare || in_assoc_list)
836 *walk_subtrees = 0;
837 return 0;
840 expr_array.release ();
842 gfc_expr_walker (e, cfe_register_funcs, NULL);
844 /* Walk through all the functions. */
846 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
848 /* Skip if the function has been replaced by a variable already. */
849 if ((*ei)->expr_type == EXPR_VARIABLE)
850 continue;
852 newvar = NULL;
853 for (j=0; j<i; j++)
855 ej = expr_array[j];
856 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
858 if (newvar == NULL)
859 newvar = create_var (*ei, "fcn");
861 if (warn_function_elimination)
862 do_warn_function_elimination (*ej);
864 free (*ej);
865 *ej = gfc_copy_expr (newvar);
868 if (newvar)
869 *ei = newvar;
872 /* We did all the necessary walking in this function. */
873 *walk_subtrees = 0;
874 return 0;
877 /* Callback function for common function elimination, called from
878 gfc_code_walker. This keeps track of the current code, in order
879 to insert statements as needed. */
881 static int
882 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
884 current_code = c;
885 inserted_block = NULL;
886 changed_statement = NULL;
888 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
889 and allocation on assigment are prohibited inside WHERE, and finally
890 masking an expression would lead to wrong-code when replacing
892 WHERE (a>0)
893 b = sum(foo(a) + foo(a))
894 END WHERE
896 with
898 WHERE (a > 0)
899 tmp = foo(a)
900 b = sum(tmp + tmp)
901 END WHERE
904 if ((*c)->op == EXEC_WHERE)
906 *walk_subtrees = 0;
907 return 0;
911 return 0;
914 /* Dummy function for expression call back, for use when we
915 really don't want to do any walking. */
917 static int
918 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
919 void *data ATTRIBUTE_UNUSED)
921 *walk_subtrees = 0;
922 return 0;
925 /* Dummy function for code callback, for use when we really
926 don't want to do anything. */
928 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
929 int *walk_subtrees ATTRIBUTE_UNUSED,
930 void *data ATTRIBUTE_UNUSED)
932 return 0;
935 /* Code callback function for converting
936 do while(a)
937 end do
938 into the equivalent
940 if (.not. a) exit
941 end do
942 This is because common function elimination would otherwise place the
943 temporary variables outside the loop. */
945 static int
946 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
947 void *data ATTRIBUTE_UNUSED)
949 gfc_code *co = *c;
950 gfc_code *c_if1, *c_if2, *c_exit;
951 gfc_code *loopblock;
952 gfc_expr *e_not, *e_cond;
954 if (co->op != EXEC_DO_WHILE)
955 return 0;
957 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
958 return 0;
960 e_cond = co->expr1;
962 /* Generate the condition of the if statement, which is .not. the original
963 statement. */
964 e_not = gfc_get_expr ();
965 e_not->ts = e_cond->ts;
966 e_not->where = e_cond->where;
967 e_not->expr_type = EXPR_OP;
968 e_not->value.op.op = INTRINSIC_NOT;
969 e_not->value.op.op1 = e_cond;
971 /* Generate the EXIT statement. */
972 c_exit = XCNEW (gfc_code);
973 c_exit->op = EXEC_EXIT;
974 c_exit->ext.which_construct = co;
975 c_exit->loc = co->loc;
977 /* Generate the IF statement. */
978 c_if2 = XCNEW (gfc_code);
979 c_if2->op = EXEC_IF;
980 c_if2->expr1 = e_not;
981 c_if2->next = c_exit;
982 c_if2->loc = co->loc;
984 /* ... plus the one to chain it to. */
985 c_if1 = XCNEW (gfc_code);
986 c_if1->op = EXEC_IF;
987 c_if1->block = c_if2;
988 c_if1->loc = co->loc;
990 /* Make the DO WHILE loop into a DO block by replacing the condition
991 with a true constant. */
992 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
994 /* Hang the generated if statement into the loop body. */
996 loopblock = co->block->next;
997 co->block->next = c_if1;
998 c_if1->next = loopblock;
1000 return 0;
1003 /* Code callback function for converting
1004 if (a) then
1006 else if (b) then
1007 end if
1009 into
1010 if (a) then
1011 else
1012 if (b) then
1013 end if
1014 end if
1016 because otherwise common function elimination would place the BLOCKs
1017 into the wrong place. */
1019 static int
1020 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1021 void *data ATTRIBUTE_UNUSED)
1023 gfc_code *co = *c;
1024 gfc_code *c_if1, *c_if2, *else_stmt;
1026 if (co->op != EXEC_IF)
1027 return 0;
1029 /* This loop starts out with the first ELSE statement. */
1030 else_stmt = co->block->block;
1032 while (else_stmt != NULL)
1034 gfc_code *next_else;
1036 /* If there is no condition, we're done. */
1037 if (else_stmt->expr1 == NULL)
1038 break;
1040 next_else = else_stmt->block;
1042 /* Generate the new IF statement. */
1043 c_if2 = XCNEW (gfc_code);
1044 c_if2->op = EXEC_IF;
1045 c_if2->expr1 = else_stmt->expr1;
1046 c_if2->next = else_stmt->next;
1047 c_if2->loc = else_stmt->loc;
1048 c_if2->block = next_else;
1050 /* ... plus the one to chain it to. */
1051 c_if1 = XCNEW (gfc_code);
1052 c_if1->op = EXEC_IF;
1053 c_if1->block = c_if2;
1054 c_if1->loc = else_stmt->loc;
1056 /* Insert the new IF after the ELSE. */
1057 else_stmt->expr1 = NULL;
1058 else_stmt->next = c_if1;
1059 else_stmt->block = NULL;
1061 else_stmt = next_else;
1063 /* Don't walk subtrees. */
1064 return 0;
1067 struct do_stack
1069 struct do_stack *prev;
1070 gfc_iterator *iter;
1071 gfc_code *code;
1072 } *stack_top;
1074 /* Recursively traverse the block of a WRITE or READ statement, and maybe
1075 optimize by replacing do loops with their analog array slices. For
1076 example:
1078 write (*,*) (a(i), i=1,4)
1080 is replaced with
1082 write (*,*) a(1:4:1) . */
1084 static bool
1085 traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
1087 gfc_code *curr;
1088 gfc_expr *new_e, *expr, *start;
1089 gfc_ref *ref;
1090 struct do_stack ds_push;
1091 int i, future_rank = 0;
1092 gfc_iterator *iters[GFC_MAX_DIMENSIONS];
1093 gfc_expr *e;
1095 /* Find the first transfer/do statement. */
1096 for (curr = code; curr; curr = curr->next)
1098 if (curr->op == EXEC_DO || curr->op == EXEC_TRANSFER)
1099 break;
1102 /* Ensure it is the only transfer/do statement because cases like
1104 write (*,*) (a(i), b(i), i=1,4)
1106 cannot be optimized. */
1108 if (!curr || curr->next)
1109 return false;
1111 if (curr->op == EXEC_DO)
1113 if (curr->ext.iterator->var->ref)
1114 return false;
1115 ds_push.prev = stack_top;
1116 ds_push.iter = curr->ext.iterator;
1117 ds_push.code = curr;
1118 stack_top = &ds_push;
1119 if (traverse_io_block (curr->block->next, has_reached, prev))
1121 if (curr != stack_top->code && !*has_reached)
1123 curr->block->next = NULL;
1124 gfc_free_statements (curr);
1126 else
1127 *has_reached = true;
1128 return true;
1130 return false;
1133 gcc_assert (curr->op == EXEC_TRANSFER);
1135 /* FIXME: Workaround for PR 80945 - array slices with deferred character
1136 lenghts do not work. Remove this section when the PR is fixed. */
1137 e = curr->expr1;
1138 if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
1139 && e->ts.deferred)
1140 return false;
1141 /* End of section to be removed. */
1143 ref = e->ref;
1144 if (!ref || ref->type != REF_ARRAY || ref->u.ar.codimen != 0 || ref->next)
1145 return false;
1147 /* Find the iterators belonging to each variable and check conditions. */
1148 for (i = 0; i < ref->u.ar.dimen; i++)
1150 if (!ref->u.ar.start[i] || ref->u.ar.start[i]->ref
1151 || ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1152 return false;
1154 start = ref->u.ar.start[i];
1155 gfc_simplify_expr (start, 0);
1156 switch (start->expr_type)
1158 case EXPR_VARIABLE:
1160 /* write (*,*) (a(i), i=a%b,1) not handled yet. */
1161 if (start->ref)
1162 return false;
1164 /* Check for (a(k), i=1,4) or ((a(j, i), i=1,4), j=1,4). */
1165 if (!stack_top || !stack_top->iter
1166 || stack_top->iter->var->symtree != start->symtree)
1168 /* Check for (a(i,i), i=1,3). */
1169 int j;
1171 for (j=0; j<i; j++)
1172 if (iters[j] && iters[j]->var->symtree == start->symtree)
1173 return false;
1175 iters[i] = NULL;
1177 else
1179 iters[i] = stack_top->iter;
1180 stack_top = stack_top->prev;
1181 future_rank++;
1183 break;
1184 case EXPR_CONSTANT:
1185 iters[i] = NULL;
1186 break;
1187 case EXPR_OP:
1188 switch (start->value.op.op)
1190 case INTRINSIC_PLUS:
1191 case INTRINSIC_TIMES:
1192 if (start->value.op.op1->expr_type != EXPR_VARIABLE)
1193 std::swap (start->value.op.op1, start->value.op.op2);
1194 gcc_fallthrough ();
1195 case INTRINSIC_MINUS:
1196 if ((start->value.op.op1->expr_type!= EXPR_VARIABLE
1197 && start->value.op.op2->expr_type != EXPR_CONSTANT)
1198 || start->value.op.op1->ref)
1199 return false;
1200 if (!stack_top || !stack_top->iter
1201 || stack_top->iter->var->symtree
1202 != start->value.op.op1->symtree)
1203 return false;
1204 iters[i] = stack_top->iter;
1205 stack_top = stack_top->prev;
1206 break;
1207 default:
1208 return false;
1210 future_rank++;
1211 break;
1212 default:
1213 return false;
1217 /* Create new expr. */
1218 new_e = gfc_copy_expr (curr->expr1);
1219 new_e->expr_type = EXPR_VARIABLE;
1220 new_e->rank = future_rank;
1221 if (curr->expr1->shape)
1222 new_e->shape = gfc_get_shape (new_e->rank);
1224 /* Assign new starts, ends and strides if necessary. */
1225 for (i = 0; i < ref->u.ar.dimen; i++)
1227 if (!iters[i])
1228 continue;
1229 start = ref->u.ar.start[i];
1230 switch (start->expr_type)
1232 case EXPR_CONSTANT:
1233 gfc_internal_error ("bad expression");
1234 break;
1235 case EXPR_VARIABLE:
1236 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1237 new_e->ref->u.ar.type = AR_SECTION;
1238 gfc_free_expr (new_e->ref->u.ar.start[i]);
1239 new_e->ref->u.ar.start[i] = gfc_copy_expr (iters[i]->start);
1240 new_e->ref->u.ar.end[i] = gfc_copy_expr (iters[i]->end);
1241 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1242 break;
1243 case EXPR_OP:
1244 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1245 new_e->ref->u.ar.type = AR_SECTION;
1246 gfc_free_expr (new_e->ref->u.ar.start[i]);
1247 expr = gfc_copy_expr (start);
1248 expr->value.op.op1 = gfc_copy_expr (iters[i]->start);
1249 new_e->ref->u.ar.start[i] = expr;
1250 gfc_simplify_expr (new_e->ref->u.ar.start[i], 0);
1251 expr = gfc_copy_expr (start);
1252 expr->value.op.op1 = gfc_copy_expr (iters[i]->end);
1253 new_e->ref->u.ar.end[i] = expr;
1254 gfc_simplify_expr (new_e->ref->u.ar.end[i], 0);
1255 switch (start->value.op.op)
1257 case INTRINSIC_MINUS:
1258 case INTRINSIC_PLUS:
1259 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1260 break;
1261 case INTRINSIC_TIMES:
1262 expr = gfc_copy_expr (start);
1263 expr->value.op.op1 = gfc_copy_expr (iters[i]->step);
1264 new_e->ref->u.ar.stride[i] = expr;
1265 gfc_simplify_expr (new_e->ref->u.ar.stride[i], 0);
1266 break;
1267 default:
1268 gfc_internal_error ("bad op");
1270 break;
1271 default:
1272 gfc_internal_error ("bad expression");
1275 curr->expr1 = new_e;
1277 /* Insert modified statement. Check whether the statement needs to be
1278 inserted at the lowest level. */
1279 if (!stack_top->iter)
1281 if (prev)
1283 curr->next = prev->next->next;
1284 prev->next = curr;
1286 else
1288 curr->next = stack_top->code->block->next->next->next;
1289 stack_top->code->block->next = curr;
1292 else
1293 stack_top->code->block->next = curr;
1294 return true;
1297 /* Function for the gfc_code_walker. If code is a READ or WRITE statement, it
1298 tries to optimize its block. */
1300 static int
1301 simplify_io_impl_do (gfc_code **code, int *walk_subtrees,
1302 void *data ATTRIBUTE_UNUSED)
1304 gfc_code **curr, *prev = NULL;
1305 struct do_stack write, first;
1306 bool b = false;
1307 *walk_subtrees = 1;
1308 if (!(*code)->block
1309 || ((*code)->block->op != EXEC_WRITE
1310 && (*code)->block->op != EXEC_READ))
1311 return 0;
1313 *walk_subtrees = 0;
1314 write.prev = NULL;
1315 write.iter = NULL;
1316 write.code = *code;
1318 for (curr = &(*code)->block; *curr; curr = &(*curr)->next)
1320 if ((*curr)->op == EXEC_DO)
1322 first.prev = &write;
1323 first.iter = (*curr)->ext.iterator;
1324 first.code = *curr;
1325 stack_top = &first;
1326 traverse_io_block ((*curr)->block->next, &b, prev);
1327 stack_top = NULL;
1329 prev = *curr;
1331 return 0;
1334 /* Optimize a namespace, including all contained namespaces. */
1336 static void
1337 optimize_namespace (gfc_namespace *ns)
1339 gfc_namespace *saved_ns = gfc_current_ns;
1340 current_ns = ns;
1341 gfc_current_ns = ns;
1342 forall_level = 0;
1343 iterator_level = 0;
1344 in_assoc_list = false;
1345 in_omp_workshare = false;
1347 gfc_code_walker (&ns->code, simplify_io_impl_do, dummy_expr_callback, NULL);
1348 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
1349 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
1350 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
1351 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
1352 if (flag_inline_matmul_limit != 0)
1354 bool found;
1357 found = false;
1358 gfc_code_walker (&ns->code, matmul_to_var_code, matmul_to_var_expr,
1359 (void *) &found);
1361 while (found);
1363 gfc_code_walker (&ns->code, matmul_temp_args, dummy_expr_callback,
1364 NULL);
1365 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
1366 NULL);
1369 /* BLOCKs are handled in the expression walker below. */
1370 for (ns = ns->contained; ns; ns = ns->sibling)
1372 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1373 optimize_namespace (ns);
1375 gfc_current_ns = saved_ns;
1378 /* Handle dependencies for allocatable strings which potentially redefine
1379 themselves in an assignment. */
1381 static void
1382 realloc_strings (gfc_namespace *ns)
1384 current_ns = ns;
1385 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1387 for (ns = ns->contained; ns; ns = ns->sibling)
1389 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1390 realloc_strings (ns);
1395 static void
1396 optimize_reduction (gfc_namespace *ns)
1398 current_ns = ns;
1399 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1400 callback_reduction, NULL);
1402 /* BLOCKs are handled in the expression walker below. */
1403 for (ns = ns->contained; ns; ns = ns->sibling)
1405 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1406 optimize_reduction (ns);
1410 /* Replace code like
1411 a = matmul(b,c) + d
1412 with
1413 a = matmul(b,c) ; a = a + d
1414 where the array function is not elemental and not allocatable
1415 and does not depend on the left-hand side.
1418 static bool
1419 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1421 gfc_expr *e;
1423 if (!*rhs)
1424 return false;
1426 e = *rhs;
1427 if (e->expr_type == EXPR_OP)
1429 switch (e->value.op.op)
1431 /* Unary operators and exponentiation: Only look at a single
1432 operand. */
1433 case INTRINSIC_NOT:
1434 case INTRINSIC_UPLUS:
1435 case INTRINSIC_UMINUS:
1436 case INTRINSIC_PARENTHESES:
1437 case INTRINSIC_POWER:
1438 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
1439 return true;
1440 break;
1442 case INTRINSIC_CONCAT:
1443 /* Do not do string concatenations. */
1444 break;
1446 default:
1447 /* Binary operators. */
1448 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1449 return true;
1451 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1452 return true;
1454 break;
1457 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
1458 && ! (e->value.function.esym
1459 && (e->value.function.esym->attr.elemental
1460 || e->value.function.esym->attr.allocatable
1461 || e->value.function.esym->ts.type != c->expr1->ts.type
1462 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
1463 && ! (e->value.function.isym
1464 && (e->value.function.isym->elemental
1465 || e->ts.type != c->expr1->ts.type
1466 || e->ts.kind != c->expr1->ts.kind))
1467 && ! gfc_inline_intrinsic_function_p (e))
1470 gfc_code *n;
1471 gfc_expr *new_expr;
1473 /* Insert a new assignment statement after the current one. */
1474 n = XCNEW (gfc_code);
1475 n->op = EXEC_ASSIGN;
1476 n->loc = c->loc;
1477 n->next = c->next;
1478 c->next = n;
1480 n->expr1 = gfc_copy_expr (c->expr1);
1481 n->expr2 = c->expr2;
1482 new_expr = gfc_copy_expr (c->expr1);
1483 c->expr2 = e;
1484 *rhs = new_expr;
1486 return true;
1490 /* Nothing to optimize. */
1491 return false;
1494 /* Remove unneeded TRIMs at the end of expressions. */
1496 static bool
1497 remove_trim (gfc_expr *rhs)
1499 bool ret;
1501 ret = false;
1502 if (!rhs)
1503 return ret;
1505 /* Check for a // b // trim(c). Looping is probably not
1506 necessary because the parser usually generates
1507 (// (// a b ) trim(c) ) , but better safe than sorry. */
1509 while (rhs->expr_type == EXPR_OP
1510 && rhs->value.op.op == INTRINSIC_CONCAT)
1511 rhs = rhs->value.op.op2;
1513 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1514 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1516 strip_function_call (rhs);
1517 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1518 remove_trim (rhs);
1519 ret = true;
1522 return ret;
1525 /* Optimizations for an assignment. */
1527 static void
1528 optimize_assignment (gfc_code * c)
1530 gfc_expr *lhs, *rhs;
1532 lhs = c->expr1;
1533 rhs = c->expr2;
1535 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1537 /* Optimize a = trim(b) to a = b. */
1538 remove_trim (rhs);
1540 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1541 if (is_empty_string (rhs))
1542 rhs->value.character.length = 0;
1545 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1546 optimize_binop_array_assignment (c, &rhs, false);
1550 /* Remove an unneeded function call, modifying the expression.
1551 This replaces the function call with the value of its
1552 first argument. The rest of the argument list is freed. */
1554 static void
1555 strip_function_call (gfc_expr *e)
1557 gfc_expr *e1;
1558 gfc_actual_arglist *a;
1560 a = e->value.function.actual;
1562 /* We should have at least one argument. */
1563 gcc_assert (a->expr != NULL);
1565 e1 = a->expr;
1567 /* Free the remaining arglist, if any. */
1568 if (a->next)
1569 gfc_free_actual_arglist (a->next);
1571 /* Graft the argument expression onto the original function. */
1572 *e = *e1;
1573 free (e1);
1577 /* Optimization of lexical comparison functions. */
1579 static bool
1580 optimize_lexical_comparison (gfc_expr *e)
1582 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1583 return false;
1585 switch (e->value.function.isym->id)
1587 case GFC_ISYM_LLE:
1588 return optimize_comparison (e, INTRINSIC_LE);
1590 case GFC_ISYM_LGE:
1591 return optimize_comparison (e, INTRINSIC_GE);
1593 case GFC_ISYM_LGT:
1594 return optimize_comparison (e, INTRINSIC_GT);
1596 case GFC_ISYM_LLT:
1597 return optimize_comparison (e, INTRINSIC_LT);
1599 default:
1600 break;
1602 return false;
1605 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1606 do CHARACTER because of possible pessimization involving character
1607 lengths. */
1609 static bool
1610 combine_array_constructor (gfc_expr *e)
1613 gfc_expr *op1, *op2;
1614 gfc_expr *scalar;
1615 gfc_expr *new_expr;
1616 gfc_constructor *c, *new_c;
1617 gfc_constructor_base oldbase, newbase;
1618 bool scalar_first;
1620 /* Array constructors have rank one. */
1621 if (e->rank != 1)
1622 return false;
1624 /* Don't try to combine association lists, this makes no sense
1625 and leads to an ICE. */
1626 if (in_assoc_list)
1627 return false;
1629 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1630 if (forall_level > 0)
1631 return false;
1633 /* Inside an iterator, things can get hairy; we are likely to create
1634 an invalid temporary variable. */
1635 if (iterator_level > 0)
1636 return false;
1638 op1 = e->value.op.op1;
1639 op2 = e->value.op.op2;
1641 if (!op1 || !op2)
1642 return false;
1644 if (op1->expr_type == EXPR_ARRAY && op2->rank == 0)
1645 scalar_first = false;
1646 else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0)
1648 scalar_first = true;
1649 op1 = e->value.op.op2;
1650 op2 = e->value.op.op1;
1652 else
1653 return false;
1655 if (op2->ts.type == BT_CHARACTER)
1656 return false;
1658 scalar = create_var (gfc_copy_expr (op2), "constr");
1660 oldbase = op1->value.constructor;
1661 newbase = NULL;
1662 e->expr_type = EXPR_ARRAY;
1664 for (c = gfc_constructor_first (oldbase); c;
1665 c = gfc_constructor_next (c))
1667 new_expr = gfc_get_expr ();
1668 new_expr->ts = e->ts;
1669 new_expr->expr_type = EXPR_OP;
1670 new_expr->rank = c->expr->rank;
1671 new_expr->where = c->expr->where;
1672 new_expr->value.op.op = e->value.op.op;
1674 if (scalar_first)
1676 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1677 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1679 else
1681 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1682 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1685 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1686 new_c->iterator = c->iterator;
1687 c->iterator = NULL;
1690 gfc_free_expr (op1);
1691 gfc_free_expr (op2);
1692 gfc_free_expr (scalar);
1694 e->value.constructor = newbase;
1695 return true;
1698 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1699 2**k into ishift(1,k) */
1701 static bool
1702 optimize_power (gfc_expr *e)
1704 gfc_expr *op1, *op2;
1705 gfc_expr *iand, *ishft;
1707 if (e->ts.type != BT_INTEGER)
1708 return false;
1710 op1 = e->value.op.op1;
1712 if (op1 == NULL || op1->expr_type != EXPR_CONSTANT)
1713 return false;
1715 if (mpz_cmp_si (op1->value.integer, -1L) == 0)
1717 gfc_free_expr (op1);
1719 op2 = e->value.op.op2;
1721 if (op2 == NULL)
1722 return false;
1724 iand = gfc_build_intrinsic_call (current_ns, GFC_ISYM_IAND,
1725 "_internal_iand", e->where, 2, op2,
1726 gfc_get_int_expr (e->ts.kind,
1727 &e->where, 1));
1729 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1730 "_internal_ishft", e->where, 2, iand,
1731 gfc_get_int_expr (e->ts.kind,
1732 &e->where, 1));
1734 e->value.op.op = INTRINSIC_MINUS;
1735 e->value.op.op1 = gfc_get_int_expr (e->ts.kind, &e->where, 1);
1736 e->value.op.op2 = ishft;
1737 return true;
1739 else if (mpz_cmp_si (op1->value.integer, 2L) == 0)
1741 gfc_free_expr (op1);
1743 op2 = e->value.op.op2;
1744 if (op2 == NULL)
1745 return false;
1747 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1748 "_internal_ishft", e->where, 2,
1749 gfc_get_int_expr (e->ts.kind,
1750 &e->where, 1),
1751 op2);
1752 *e = *ishft;
1753 return true;
1756 else if (mpz_cmp_si (op1->value.integer, 1L) == 0)
1758 op2 = e->value.op.op2;
1759 if (op2 == NULL)
1760 return false;
1762 gfc_free_expr (op1);
1763 gfc_free_expr (op2);
1765 e->expr_type = EXPR_CONSTANT;
1766 e->value.op.op1 = NULL;
1767 e->value.op.op2 = NULL;
1768 mpz_init_set_si (e->value.integer, 1);
1769 /* Typespec and location are still OK. */
1770 return true;
1773 return false;
1776 /* Recursive optimization of operators. */
1778 static bool
1779 optimize_op (gfc_expr *e)
1781 bool changed;
1783 gfc_intrinsic_op op = e->value.op.op;
1785 changed = false;
1787 /* Only use new-style comparisons. */
1788 switch(op)
1790 case INTRINSIC_EQ_OS:
1791 op = INTRINSIC_EQ;
1792 break;
1794 case INTRINSIC_GE_OS:
1795 op = INTRINSIC_GE;
1796 break;
1798 case INTRINSIC_LE_OS:
1799 op = INTRINSIC_LE;
1800 break;
1802 case INTRINSIC_NE_OS:
1803 op = INTRINSIC_NE;
1804 break;
1806 case INTRINSIC_GT_OS:
1807 op = INTRINSIC_GT;
1808 break;
1810 case INTRINSIC_LT_OS:
1811 op = INTRINSIC_LT;
1812 break;
1814 default:
1815 break;
1818 switch (op)
1820 case INTRINSIC_EQ:
1821 case INTRINSIC_GE:
1822 case INTRINSIC_LE:
1823 case INTRINSIC_NE:
1824 case INTRINSIC_GT:
1825 case INTRINSIC_LT:
1826 changed = optimize_comparison (e, op);
1828 gcc_fallthrough ();
1829 /* Look at array constructors. */
1830 case INTRINSIC_PLUS:
1831 case INTRINSIC_MINUS:
1832 case INTRINSIC_TIMES:
1833 case INTRINSIC_DIVIDE:
1834 return combine_array_constructor (e) || changed;
1836 case INTRINSIC_POWER:
1837 return optimize_power (e);
1839 default:
1840 break;
1843 return false;
1847 /* Return true if a constant string contains only blanks. */
1849 static bool
1850 is_empty_string (gfc_expr *e)
1852 int i;
1854 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1855 return false;
1857 for (i=0; i < e->value.character.length; i++)
1859 if (e->value.character.string[i] != ' ')
1860 return false;
1863 return true;
1867 /* Insert a call to the intrinsic len_trim. Use a different name for
1868 the symbol tree so we don't run into trouble when the user has
1869 renamed len_trim for some reason. */
1871 static gfc_expr*
1872 get_len_trim_call (gfc_expr *str, int kind)
1874 gfc_expr *fcn;
1875 gfc_actual_arglist *actual_arglist, *next;
1877 fcn = gfc_get_expr ();
1878 fcn->expr_type = EXPR_FUNCTION;
1879 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1880 actual_arglist = gfc_get_actual_arglist ();
1881 actual_arglist->expr = str;
1882 next = gfc_get_actual_arglist ();
1883 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, kind);
1884 actual_arglist->next = next;
1886 fcn->value.function.actual = actual_arglist;
1887 fcn->where = str->where;
1888 fcn->ts.type = BT_INTEGER;
1889 fcn->ts.kind = gfc_charlen_int_kind;
1891 gfc_get_sym_tree ("__internal_len_trim", current_ns, &fcn->symtree, false);
1892 fcn->symtree->n.sym->ts = fcn->ts;
1893 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1894 fcn->symtree->n.sym->attr.function = 1;
1895 fcn->symtree->n.sym->attr.elemental = 1;
1896 fcn->symtree->n.sym->attr.referenced = 1;
1897 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
1898 gfc_commit_symbol (fcn->symtree->n.sym);
1900 return fcn;
1903 /* Optimize expressions for equality. */
1905 static bool
1906 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1908 gfc_expr *op1, *op2;
1909 bool change;
1910 int eq;
1911 bool result;
1912 gfc_actual_arglist *firstarg, *secondarg;
1914 if (e->expr_type == EXPR_OP)
1916 firstarg = NULL;
1917 secondarg = NULL;
1918 op1 = e->value.op.op1;
1919 op2 = e->value.op.op2;
1921 else if (e->expr_type == EXPR_FUNCTION)
1923 /* One of the lexical comparison functions. */
1924 firstarg = e->value.function.actual;
1925 secondarg = firstarg->next;
1926 op1 = firstarg->expr;
1927 op2 = secondarg->expr;
1929 else
1930 gcc_unreachable ();
1932 /* Strip off unneeded TRIM calls from string comparisons. */
1934 change = remove_trim (op1);
1936 if (remove_trim (op2))
1937 change = true;
1939 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1940 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
1941 handles them well). However, there are also cases that need a non-scalar
1942 argument. For example the any intrinsic. See PR 45380. */
1943 if (e->rank > 0)
1944 return change;
1946 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
1947 len_trim(a) != 0 */
1948 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
1949 && (op == INTRINSIC_EQ || op == INTRINSIC_NE))
1951 bool empty_op1, empty_op2;
1952 empty_op1 = is_empty_string (op1);
1953 empty_op2 = is_empty_string (op2);
1955 if (empty_op1 || empty_op2)
1957 gfc_expr *fcn;
1958 gfc_expr *zero;
1959 gfc_expr *str;
1961 /* This can only happen when an error for comparing
1962 characters of different kinds has already been issued. */
1963 if (empty_op1 && empty_op2)
1964 return false;
1966 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
1967 str = empty_op1 ? op2 : op1;
1969 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
1972 if (empty_op1)
1973 gfc_free_expr (op1);
1974 else
1975 gfc_free_expr (op2);
1977 op1 = fcn;
1978 op2 = zero;
1979 e->value.op.op1 = fcn;
1980 e->value.op.op2 = zero;
1985 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
1987 if (flag_finite_math_only
1988 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
1989 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
1991 eq = gfc_dep_compare_expr (op1, op2);
1992 if (eq <= -2)
1994 /* Replace A // B < A // C with B < C, and A // B < C // B
1995 with A < C. */
1996 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
1997 && op1->expr_type == EXPR_OP
1998 && op1->value.op.op == INTRINSIC_CONCAT
1999 && op2->expr_type == EXPR_OP
2000 && op2->value.op.op == INTRINSIC_CONCAT)
2002 gfc_expr *op1_left = op1->value.op.op1;
2003 gfc_expr *op2_left = op2->value.op.op1;
2004 gfc_expr *op1_right = op1->value.op.op2;
2005 gfc_expr *op2_right = op2->value.op.op2;
2007 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
2009 /* Watch out for 'A ' // x vs. 'A' // x. */
2011 if (op1_left->expr_type == EXPR_CONSTANT
2012 && op2_left->expr_type == EXPR_CONSTANT
2013 && op1_left->value.character.length
2014 != op2_left->value.character.length)
2015 return change;
2016 else
2018 free (op1_left);
2019 free (op2_left);
2020 if (firstarg)
2022 firstarg->expr = op1_right;
2023 secondarg->expr = op2_right;
2025 else
2027 e->value.op.op1 = op1_right;
2028 e->value.op.op2 = op2_right;
2030 optimize_comparison (e, op);
2031 return true;
2034 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
2036 free (op1_right);
2037 free (op2_right);
2038 if (firstarg)
2040 firstarg->expr = op1_left;
2041 secondarg->expr = op2_left;
2043 else
2045 e->value.op.op1 = op1_left;
2046 e->value.op.op2 = op2_left;
2049 optimize_comparison (e, op);
2050 return true;
2054 else
2056 /* eq can only be -1, 0 or 1 at this point. */
2057 switch (op)
2059 case INTRINSIC_EQ:
2060 result = eq == 0;
2061 break;
2063 case INTRINSIC_GE:
2064 result = eq >= 0;
2065 break;
2067 case INTRINSIC_LE:
2068 result = eq <= 0;
2069 break;
2071 case INTRINSIC_NE:
2072 result = eq != 0;
2073 break;
2075 case INTRINSIC_GT:
2076 result = eq > 0;
2077 break;
2079 case INTRINSIC_LT:
2080 result = eq < 0;
2081 break;
2083 default:
2084 gfc_internal_error ("illegal OP in optimize_comparison");
2085 break;
2088 /* Replace the expression by a constant expression. The typespec
2089 and where remains the way it is. */
2090 free (op1);
2091 free (op2);
2092 e->expr_type = EXPR_CONSTANT;
2093 e->value.logical = result;
2094 return true;
2098 return change;
2101 /* Optimize a trim function by replacing it with an equivalent substring
2102 involving a call to len_trim. This only works for expressions where
2103 variables are trimmed. Return true if anything was modified. */
2105 static bool
2106 optimize_trim (gfc_expr *e)
2108 gfc_expr *a;
2109 gfc_ref *ref;
2110 gfc_expr *fcn;
2111 gfc_ref **rr = NULL;
2113 /* Don't do this optimization within an argument list, because
2114 otherwise aliasing issues may occur. */
2116 if (count_arglist != 1)
2117 return false;
2119 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
2120 || e->value.function.isym == NULL
2121 || e->value.function.isym->id != GFC_ISYM_TRIM)
2122 return false;
2124 a = e->value.function.actual->expr;
2126 if (a->expr_type != EXPR_VARIABLE)
2127 return false;
2129 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
2131 if (a->symtree->n.sym->attr.allocatable)
2132 return false;
2134 /* Follow all references to find the correct place to put the newly
2135 created reference. FIXME: Also handle substring references and
2136 array references. Array references cause strange regressions at
2137 the moment. */
2139 if (a->ref)
2141 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
2143 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
2144 return false;
2148 strip_function_call (e);
2150 if (e->ref == NULL)
2151 rr = &(e->ref);
2153 /* Create the reference. */
2155 ref = gfc_get_ref ();
2156 ref->type = REF_SUBSTRING;
2158 /* Set the start of the reference. */
2160 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
2162 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
2164 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_default_integer_kind);
2166 /* Set the end of the reference to the call to len_trim. */
2168 ref->u.ss.end = fcn;
2169 gcc_assert (rr != NULL && *rr == NULL);
2170 *rr = ref;
2171 return true;
2174 /* Optimize minloc(b), where b is rank 1 array, into
2175 (/ minloc(b, dim=1) /), and similarly for maxloc,
2176 as the latter forms are expanded inline. */
2178 static void
2179 optimize_minmaxloc (gfc_expr **e)
2181 gfc_expr *fn = *e;
2182 gfc_actual_arglist *a;
2183 char *name, *p;
2185 if (fn->rank != 1
2186 || fn->value.function.actual == NULL
2187 || fn->value.function.actual->expr == NULL
2188 || fn->value.function.actual->expr->rank != 1)
2189 return;
2191 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
2192 (*e)->shape = fn->shape;
2193 fn->rank = 0;
2194 fn->shape = NULL;
2195 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
2197 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
2198 strcpy (name, fn->value.function.name);
2199 p = strstr (name, "loc0");
2200 p[3] = '1';
2201 fn->value.function.name = gfc_get_string ("%s", name);
2202 if (fn->value.function.actual->next)
2204 a = fn->value.function.actual->next;
2205 gcc_assert (a->expr == NULL);
2207 else
2209 a = gfc_get_actual_arglist ();
2210 fn->value.function.actual->next = a;
2212 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
2213 &fn->where);
2214 mpz_set_ui (a->expr->value.integer, 1);
2217 /* Callback function for code checking that we do not pass a DO variable to an
2218 INTENT(OUT) or INTENT(INOUT) dummy variable. */
2220 static int
2221 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2222 void *data ATTRIBUTE_UNUSED)
2224 gfc_code *co;
2225 int i;
2226 gfc_formal_arglist *f;
2227 gfc_actual_arglist *a;
2228 gfc_code *cl;
2230 co = *c;
2232 /* If the doloop_list grew, we have to truncate it here. */
2234 if ((unsigned) doloop_level < doloop_list.length())
2235 doloop_list.truncate (doloop_level);
2237 switch (co->op)
2239 case EXEC_DO:
2241 if (co->ext.iterator && co->ext.iterator->var)
2242 doloop_list.safe_push (co);
2243 else
2244 doloop_list.safe_push ((gfc_code *) NULL);
2245 break;
2247 case EXEC_CALL:
2249 if (co->resolved_sym == NULL)
2250 break;
2252 f = gfc_sym_get_dummy_args (co->resolved_sym);
2254 /* Withot a formal arglist, there is only unknown INTENT,
2255 which we don't check for. */
2256 if (f == NULL)
2257 break;
2259 a = co->ext.actual;
2261 while (a && f)
2263 FOR_EACH_VEC_ELT (doloop_list, i, cl)
2265 gfc_symbol *do_sym;
2267 if (cl == NULL)
2268 break;
2270 do_sym = cl->ext.iterator->var->symtree->n.sym;
2272 if (a->expr && a->expr->symtree
2273 && a->expr->symtree->n.sym == do_sym)
2275 if (f->sym->attr.intent == INTENT_OUT)
2276 gfc_error_now ("Variable %qs at %L set to undefined "
2277 "value inside loop beginning at %L as "
2278 "INTENT(OUT) argument to subroutine %qs",
2279 do_sym->name, &a->expr->where,
2280 &doloop_list[i]->loc,
2281 co->symtree->n.sym->name);
2282 else if (f->sym->attr.intent == INTENT_INOUT)
2283 gfc_error_now ("Variable %qs at %L not definable inside "
2284 "loop beginning at %L as INTENT(INOUT) "
2285 "argument to subroutine %qs",
2286 do_sym->name, &a->expr->where,
2287 &doloop_list[i]->loc,
2288 co->symtree->n.sym->name);
2291 a = a->next;
2292 f = f->next;
2294 break;
2296 default:
2297 break;
2299 return 0;
2302 /* Callback function for functions checking that we do not pass a DO variable
2303 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
2305 static int
2306 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2307 void *data ATTRIBUTE_UNUSED)
2309 gfc_formal_arglist *f;
2310 gfc_actual_arglist *a;
2311 gfc_expr *expr;
2312 gfc_code *dl;
2313 int i;
2315 expr = *e;
2316 if (expr->expr_type != EXPR_FUNCTION)
2317 return 0;
2319 /* Intrinsic functions don't modify their arguments. */
2321 if (expr->value.function.isym)
2322 return 0;
2324 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
2326 /* Without a formal arglist, there is only unknown INTENT,
2327 which we don't check for. */
2328 if (f == NULL)
2329 return 0;
2331 a = expr->value.function.actual;
2333 while (a && f)
2335 FOR_EACH_VEC_ELT (doloop_list, i, dl)
2337 gfc_symbol *do_sym;
2339 if (dl == NULL)
2340 break;
2342 do_sym = dl->ext.iterator->var->symtree->n.sym;
2344 if (a->expr && a->expr->symtree
2345 && a->expr->symtree->n.sym == do_sym)
2347 if (f->sym->attr.intent == INTENT_OUT)
2348 gfc_error_now ("Variable %qs at %L set to undefined value "
2349 "inside loop beginning at %L as INTENT(OUT) "
2350 "argument to function %qs", do_sym->name,
2351 &a->expr->where, &doloop_list[i]->loc,
2352 expr->symtree->n.sym->name);
2353 else if (f->sym->attr.intent == INTENT_INOUT)
2354 gfc_error_now ("Variable %qs at %L not definable inside loop"
2355 " beginning at %L as INTENT(INOUT) argument to"
2356 " function %qs", do_sym->name,
2357 &a->expr->where, &doloop_list[i]->loc,
2358 expr->symtree->n.sym->name);
2361 a = a->next;
2362 f = f->next;
2365 return 0;
2368 static void
2369 doloop_warn (gfc_namespace *ns)
2371 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
2374 /* This selction deals with inlining calls to MATMUL. */
2376 /* Replace calls to matmul outside of straight assignments with a temporary
2377 variable so that later inlining will work. */
2379 static int
2380 matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
2381 void *data)
2383 gfc_expr *e, *n;
2384 bool *found = (bool *) data;
2386 e = *ep;
2388 if (e->expr_type != EXPR_FUNCTION
2389 || e->value.function.isym == NULL
2390 || e->value.function.isym->id != GFC_ISYM_MATMUL)
2391 return 0;
2393 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2394 || in_where)
2395 return 0;
2397 /* Check if this is already in the form c = matmul(a,b). */
2399 if ((*current_code)->expr2 == e)
2400 return 0;
2402 n = create_var (e, "matmul");
2404 /* If create_var is unable to create a variable (for example if
2405 -fno-realloc-lhs is in force with a variable that does not have bounds
2406 known at compile-time), just return. */
2408 if (n == NULL)
2409 return 0;
2411 *ep = n;
2412 *found = true;
2413 return 0;
2416 /* Set current_code and associated variables so that matmul_to_var_expr can
2417 work. */
2419 static int
2420 matmul_to_var_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2421 void *data ATTRIBUTE_UNUSED)
2423 if (current_code != c)
2425 current_code = c;
2426 inserted_block = NULL;
2427 changed_statement = NULL;
2430 return 0;
2434 /* Take a statement of the shape c = matmul(a,b) and create temporaries
2435 for a and b if there is a dependency between the arguments and the
2436 result variable or if a or b are the result of calculations that cannot
2437 be handled by the inliner. */
2439 static int
2440 matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2441 void *data ATTRIBUTE_UNUSED)
2443 gfc_expr *expr1, *expr2;
2444 gfc_code *co;
2445 gfc_actual_arglist *a, *b;
2446 bool a_tmp, b_tmp;
2447 gfc_expr *matrix_a, *matrix_b;
2448 bool conjg_a, conjg_b, transpose_a, transpose_b;
2450 co = *c;
2452 if (co->op != EXEC_ASSIGN)
2453 return 0;
2455 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2456 || in_where)
2457 return 0;
2459 /* This has some duplication with inline_matmul_assign. This
2460 is because the creation of temporary variables could still fail,
2461 and inline_matmul_assign still needs to be able to handle these
2462 cases. */
2463 expr1 = co->expr1;
2464 expr2 = co->expr2;
2466 if (expr2->expr_type != EXPR_FUNCTION
2467 || expr2->value.function.isym == NULL
2468 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
2469 return 0;
2471 a_tmp = false;
2472 a = expr2->value.function.actual;
2473 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
2474 if (matrix_a != NULL)
2476 if (matrix_a->expr_type == EXPR_VARIABLE
2477 && (gfc_check_dependency (matrix_a, expr1, true)
2478 || has_dimen_vector_ref (matrix_a)))
2479 a_tmp = true;
2481 else
2482 a_tmp = true;
2484 b_tmp = false;
2485 b = a->next;
2486 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
2487 if (matrix_b != NULL)
2489 if (matrix_b->expr_type == EXPR_VARIABLE
2490 && (gfc_check_dependency (matrix_b, expr1, true)
2491 || has_dimen_vector_ref (matrix_b)))
2492 b_tmp = true;
2494 else
2495 b_tmp = true;
2497 if (!a_tmp && !b_tmp)
2498 return 0;
2500 current_code = c;
2501 inserted_block = NULL;
2502 changed_statement = NULL;
2503 if (a_tmp)
2505 gfc_expr *at;
2506 at = create_var (a->expr,"mma");
2507 if (at)
2508 a->expr = at;
2510 if (b_tmp)
2512 gfc_expr *bt;
2513 bt = create_var (b->expr,"mmb");
2514 if (bt)
2515 b->expr = bt;
2517 return 0;
2520 /* Auxiliary function to build and simplify an array inquiry function.
2521 dim is zero-based. */
2523 static gfc_expr *
2524 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim)
2526 gfc_expr *fcn;
2527 gfc_expr *dim_arg, *kind;
2528 const char *name;
2529 gfc_expr *ec;
2531 switch (id)
2533 case GFC_ISYM_LBOUND:
2534 name = "_gfortran_lbound";
2535 break;
2537 case GFC_ISYM_UBOUND:
2538 name = "_gfortran_ubound";
2539 break;
2541 case GFC_ISYM_SIZE:
2542 name = "_gfortran_size";
2543 break;
2545 default:
2546 gcc_unreachable ();
2549 dim_arg = gfc_get_int_expr (gfc_default_integer_kind, &e->where, dim);
2550 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2551 gfc_index_integer_kind);
2553 ec = gfc_copy_expr (e);
2554 fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3,
2555 ec, dim_arg, kind);
2556 gfc_simplify_expr (fcn, 0);
2557 return fcn;
2560 /* Builds a logical expression. */
2562 static gfc_expr*
2563 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2565 gfc_typespec ts;
2566 gfc_expr *res;
2568 ts.type = BT_LOGICAL;
2569 ts.kind = gfc_default_logical_kind;
2570 res = gfc_get_expr ();
2571 res->where = e1->where;
2572 res->expr_type = EXPR_OP;
2573 res->value.op.op = op;
2574 res->value.op.op1 = e1;
2575 res->value.op.op2 = e2;
2576 res->ts = ts;
2578 return res;
2582 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
2583 compatible typespecs. */
2585 static gfc_expr *
2586 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2588 gfc_expr *res;
2590 res = gfc_get_expr ();
2591 res->ts = e1->ts;
2592 res->where = e1->where;
2593 res->expr_type = EXPR_OP;
2594 res->value.op.op = op;
2595 res->value.op.op1 = e1;
2596 res->value.op.op2 = e2;
2597 gfc_simplify_expr (res, 0);
2598 return res;
2601 /* Generate the IF statement for a runtime check if we want to do inlining or
2602 not - putting in the code for both branches and putting it into the syntax
2603 tree is the caller's responsibility. For fixed array sizes, this should be
2604 removed by DCE. Only called for rank-two matrices A and B. */
2606 static gfc_code *
2607 inline_limit_check (gfc_expr *a, gfc_expr *b, enum matrix_case m_case)
2609 gfc_expr *inline_limit;
2610 gfc_code *if_1, *if_2, *else_2;
2611 gfc_expr *b2, *a2, *a1, *m1, *m2;
2612 gfc_typespec ts;
2613 gfc_expr *cond;
2615 gcc_assert (m_case == A2B2 || m_case == A2B2T || m_case == A2TB2);
2617 /* Calculation is done in real to avoid integer overflow. */
2619 inline_limit = gfc_get_constant_expr (BT_REAL, gfc_default_real_kind,
2620 &a->where);
2621 mpfr_set_si (inline_limit->value.real, flag_inline_matmul_limit,
2622 GFC_RND_MODE);
2623 mpfr_pow_ui (inline_limit->value.real, inline_limit->value.real, 3,
2624 GFC_RND_MODE);
2626 a1 = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2627 a2 = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
2628 b2 = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2630 gfc_clear_ts (&ts);
2631 ts.type = BT_REAL;
2632 ts.kind = gfc_default_real_kind;
2633 gfc_convert_type_warn (a1, &ts, 2, 0);
2634 gfc_convert_type_warn (a2, &ts, 2, 0);
2635 gfc_convert_type_warn (b2, &ts, 2, 0);
2637 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
2638 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
2640 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
2641 gfc_simplify_expr (cond, 0);
2643 else_2 = XCNEW (gfc_code);
2644 else_2->op = EXEC_IF;
2645 else_2->loc = a->where;
2647 if_2 = XCNEW (gfc_code);
2648 if_2->op = EXEC_IF;
2649 if_2->expr1 = cond;
2650 if_2->loc = a->where;
2651 if_2->block = else_2;
2653 if_1 = XCNEW (gfc_code);
2654 if_1->op = EXEC_IF;
2655 if_1->block = if_2;
2656 if_1->loc = a->where;
2658 return if_1;
2662 /* Insert code to issue a runtime error if the expressions are not equal. */
2664 static gfc_code *
2665 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
2667 gfc_expr *cond;
2668 gfc_code *if_1, *if_2;
2669 gfc_code *c;
2670 gfc_actual_arglist *a1, *a2, *a3;
2672 gcc_assert (e1->where.lb);
2673 /* Build the call to runtime_error. */
2674 c = XCNEW (gfc_code);
2675 c->op = EXEC_CALL;
2676 c->loc = e1->where;
2678 /* Get a null-terminated message string. */
2680 a1 = gfc_get_actual_arglist ();
2681 a1->expr = gfc_get_character_expr (gfc_default_character_kind, &e1->where,
2682 msg, strlen(msg)+1);
2683 c->ext.actual = a1;
2685 /* Pass the value of the first expression. */
2686 a2 = gfc_get_actual_arglist ();
2687 a2->expr = gfc_copy_expr (e1);
2688 a1->next = a2;
2690 /* Pass the value of the second expression. */
2691 a3 = gfc_get_actual_arglist ();
2692 a3->expr = gfc_copy_expr (e2);
2693 a2->next = a3;
2695 gfc_check_fe_runtime_error (c->ext.actual);
2696 gfc_resolve_fe_runtime_error (c);
2698 if_2 = XCNEW (gfc_code);
2699 if_2->op = EXEC_IF;
2700 if_2->loc = e1->where;
2701 if_2->next = c;
2703 if_1 = XCNEW (gfc_code);
2704 if_1->op = EXEC_IF;
2705 if_1->block = if_2;
2706 if_1->loc = e1->where;
2708 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
2709 gfc_simplify_expr (cond, 0);
2710 if_2->expr1 = cond;
2712 return if_1;
2715 /* Handle matrix reallocation. Caller is responsible to insert into
2716 the code tree.
2718 For the two-dimensional case, build
2720 if (allocated(c)) then
2721 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
2722 deallocate(c)
2723 allocate (c(size(a,1), size(b,2)))
2724 end if
2725 else
2726 allocate (c(size(a,1),size(b,2)))
2727 end if
2729 and for the other cases correspondingly.
2732 static gfc_code *
2733 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
2734 enum matrix_case m_case)
2737 gfc_expr *allocated, *alloc_expr;
2738 gfc_code *if_alloc_1, *if_alloc_2, *if_size_1, *if_size_2;
2739 gfc_code *else_alloc;
2740 gfc_code *deallocate, *allocate1, *allocate_else;
2741 gfc_array_ref *ar;
2742 gfc_expr *cond, *ne1, *ne2;
2744 if (warn_realloc_lhs)
2745 gfc_warning (OPT_Wrealloc_lhs,
2746 "Code for reallocating the allocatable array at %L will "
2747 "be added", &c->where);
2749 alloc_expr = gfc_copy_expr (c);
2751 ar = gfc_find_array_ref (alloc_expr);
2752 gcc_assert (ar && ar->type == AR_FULL);
2754 /* c comes in as a full ref. Change it into a copy and make it into an
2755 element ref so it has the right form for for ALLOCATE. In the same
2756 switch statement, also generate the size comparison for the secod IF
2757 statement. */
2759 ar->type = AR_ELEMENT;
2761 switch (m_case)
2763 case A2B2:
2764 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2765 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2766 ne1 = build_logical_expr (INTRINSIC_NE,
2767 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2768 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
2769 ne2 = build_logical_expr (INTRINSIC_NE,
2770 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
2771 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2772 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
2773 break;
2775 case A2B2T:
2776 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2777 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
2779 ne1 = build_logical_expr (INTRINSIC_NE,
2780 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2781 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
2782 ne2 = build_logical_expr (INTRINSIC_NE,
2783 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
2784 get_array_inq_function (GFC_ISYM_SIZE, b, 1));
2785 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
2786 break;
2788 case A2TB2:
2790 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
2791 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2793 ne1 = build_logical_expr (INTRINSIC_NE,
2794 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2795 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
2796 ne2 = build_logical_expr (INTRINSIC_NE,
2797 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
2798 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2799 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
2800 break;
2802 case A2B1:
2803 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2804 cond = build_logical_expr (INTRINSIC_NE,
2805 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2806 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
2807 break;
2809 case A1B2:
2810 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2811 cond = build_logical_expr (INTRINSIC_NE,
2812 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2813 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2814 break;
2816 default:
2817 gcc_unreachable();
2821 gfc_simplify_expr (cond, 0);
2823 /* We need two identical allocate statements in two
2824 branches of the IF statement. */
2826 allocate1 = XCNEW (gfc_code);
2827 allocate1->op = EXEC_ALLOCATE;
2828 allocate1->ext.alloc.list = gfc_get_alloc ();
2829 allocate1->loc = c->where;
2830 allocate1->ext.alloc.list->expr = gfc_copy_expr (alloc_expr);
2832 allocate_else = XCNEW (gfc_code);
2833 allocate_else->op = EXEC_ALLOCATE;
2834 allocate_else->ext.alloc.list = gfc_get_alloc ();
2835 allocate_else->loc = c->where;
2836 allocate_else->ext.alloc.list->expr = alloc_expr;
2838 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
2839 "_gfortran_allocated", c->where,
2840 1, gfc_copy_expr (c));
2842 deallocate = XCNEW (gfc_code);
2843 deallocate->op = EXEC_DEALLOCATE;
2844 deallocate->ext.alloc.list = gfc_get_alloc ();
2845 deallocate->ext.alloc.list->expr = gfc_copy_expr (c);
2846 deallocate->next = allocate1;
2847 deallocate->loc = c->where;
2849 if_size_2 = XCNEW (gfc_code);
2850 if_size_2->op = EXEC_IF;
2851 if_size_2->expr1 = cond;
2852 if_size_2->loc = c->where;
2853 if_size_2->next = deallocate;
2855 if_size_1 = XCNEW (gfc_code);
2856 if_size_1->op = EXEC_IF;
2857 if_size_1->block = if_size_2;
2858 if_size_1->loc = c->where;
2860 else_alloc = XCNEW (gfc_code);
2861 else_alloc->op = EXEC_IF;
2862 else_alloc->loc = c->where;
2863 else_alloc->next = allocate_else;
2865 if_alloc_2 = XCNEW (gfc_code);
2866 if_alloc_2->op = EXEC_IF;
2867 if_alloc_2->expr1 = allocated;
2868 if_alloc_2->loc = c->where;
2869 if_alloc_2->next = if_size_1;
2870 if_alloc_2->block = else_alloc;
2872 if_alloc_1 = XCNEW (gfc_code);
2873 if_alloc_1->op = EXEC_IF;
2874 if_alloc_1->block = if_alloc_2;
2875 if_alloc_1->loc = c->where;
2877 return if_alloc_1;
2880 /* Callback function for has_function_or_op. */
2882 static int
2883 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2884 void *data ATTRIBUTE_UNUSED)
2886 if ((*e) == 0)
2887 return 0;
2888 else
2889 return (*e)->expr_type == EXPR_FUNCTION
2890 || (*e)->expr_type == EXPR_OP;
2893 /* Returns true if the expression contains a function. */
2895 static bool
2896 has_function_or_op (gfc_expr **e)
2898 if (e == NULL)
2899 return false;
2900 else
2901 return gfc_expr_walker (e, is_function_or_op, NULL);
2904 /* Freeze (assign to a temporary variable) a single expression. */
2906 static void
2907 freeze_expr (gfc_expr **ep)
2909 gfc_expr *ne;
2910 if (has_function_or_op (ep))
2912 ne = create_var (*ep, "freeze");
2913 *ep = ne;
2917 /* Go through an expression's references and assign them to temporary
2918 variables if they contain functions. This is usually done prior to
2919 front-end scalarization to avoid multiple invocations of functions. */
2921 static void
2922 freeze_references (gfc_expr *e)
2924 gfc_ref *r;
2925 gfc_array_ref *ar;
2926 int i;
2928 for (r=e->ref; r; r=r->next)
2930 if (r->type == REF_SUBSTRING)
2932 if (r->u.ss.start != NULL)
2933 freeze_expr (&r->u.ss.start);
2935 if (r->u.ss.end != NULL)
2936 freeze_expr (&r->u.ss.end);
2938 else if (r->type == REF_ARRAY)
2940 ar = &r->u.ar;
2941 switch (ar->type)
2943 case AR_FULL:
2944 break;
2946 case AR_SECTION:
2947 for (i=0; i<ar->dimen; i++)
2949 if (ar->dimen_type[i] == DIMEN_RANGE)
2951 freeze_expr (&ar->start[i]);
2952 freeze_expr (&ar->end[i]);
2953 freeze_expr (&ar->stride[i]);
2955 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
2957 freeze_expr (&ar->start[i]);
2960 break;
2962 case AR_ELEMENT:
2963 for (i=0; i<ar->dimen; i++)
2964 freeze_expr (&ar->start[i]);
2965 break;
2967 default:
2968 break;
2974 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
2976 static gfc_expr *
2977 convert_to_index_kind (gfc_expr *e)
2979 gfc_expr *res;
2981 gcc_assert (e != NULL);
2983 res = gfc_copy_expr (e);
2985 gcc_assert (e->ts.type == BT_INTEGER);
2987 if (res->ts.kind != gfc_index_integer_kind)
2989 gfc_typespec ts;
2990 gfc_clear_ts (&ts);
2991 ts.type = BT_INTEGER;
2992 ts.kind = gfc_index_integer_kind;
2994 gfc_convert_type_warn (e, &ts, 2, 0);
2997 return res;
3000 /* Function to create a DO loop including creation of the
3001 iteration variable. gfc_expr are copied.*/
3003 static gfc_code *
3004 create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where,
3005 gfc_namespace *ns, char *vname)
3008 char name[GFC_MAX_SYMBOL_LEN +1];
3009 gfc_symtree *symtree;
3010 gfc_symbol *symbol;
3011 gfc_expr *i;
3012 gfc_code *n, *n2;
3014 /* Create an expression for the iteration variable. */
3015 if (vname)
3016 sprintf (name, "__var_%d_do_%s", var_num++, vname);
3017 else
3018 sprintf (name, "__var_%d_do", var_num++);
3021 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
3022 gcc_unreachable ();
3024 /* Create the loop variable. */
3026 symbol = symtree->n.sym;
3027 symbol->ts.type = BT_INTEGER;
3028 symbol->ts.kind = gfc_index_integer_kind;
3029 symbol->attr.flavor = FL_VARIABLE;
3030 symbol->attr.referenced = 1;
3031 symbol->attr.dimension = 0;
3032 symbol->attr.fe_temp = 1;
3033 gfc_commit_symbol (symbol);
3035 i = gfc_get_expr ();
3036 i->expr_type = EXPR_VARIABLE;
3037 i->ts = symbol->ts;
3038 i->rank = 0;
3039 i->where = *where;
3040 i->symtree = symtree;
3042 /* ... and the nested DO statements. */
3043 n = XCNEW (gfc_code);
3044 n->op = EXEC_DO;
3045 n->loc = *where;
3046 n->ext.iterator = gfc_get_iterator ();
3047 n->ext.iterator->var = i;
3048 n->ext.iterator->start = convert_to_index_kind (start);
3049 n->ext.iterator->end = convert_to_index_kind (end);
3050 if (step)
3051 n->ext.iterator->step = convert_to_index_kind (step);
3052 else
3053 n->ext.iterator->step = gfc_get_int_expr (gfc_index_integer_kind,
3054 where, 1);
3056 n2 = XCNEW (gfc_code);
3057 n2->op = EXEC_DO;
3058 n2->loc = *where;
3059 n2->next = NULL;
3060 n->block = n2;
3061 return n;
3064 /* Get the upper bound of the DO loops for matmul along a dimension. This
3065 is one-based. */
3067 static gfc_expr*
3068 get_size_m1 (gfc_expr *e, int dimen)
3070 mpz_t size;
3071 gfc_expr *res;
3073 if (gfc_array_dimen_size (e, dimen - 1, &size))
3075 res = gfc_get_constant_expr (BT_INTEGER,
3076 gfc_index_integer_kind, &e->where);
3077 mpz_sub_ui (res->value.integer, size, 1);
3078 mpz_clear (size);
3080 else
3082 res = get_operand (INTRINSIC_MINUS,
3083 get_array_inq_function (GFC_ISYM_SIZE, e, dimen),
3084 gfc_get_int_expr (gfc_index_integer_kind,
3085 &e->where, 1));
3086 gfc_simplify_expr (res, 0);
3089 return res;
3092 /* Function to return a scalarized expression. It is assumed that indices are
3093 zero based to make generation of DO loops easier. A zero as index will
3094 access the first element along a dimension. Single element references will
3095 be skipped. A NULL as an expression will be replaced by a full reference.
3096 This assumes that the index loops have gfc_index_integer_kind, and that all
3097 references have been frozen. */
3099 static gfc_expr*
3100 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
3102 gfc_array_ref *ar;
3103 int i;
3104 int rank;
3105 gfc_expr *e;
3106 int i_index;
3107 bool was_fullref;
3109 e = gfc_copy_expr(e_in);
3111 rank = e->rank;
3113 ar = gfc_find_array_ref (e);
3115 /* We scalarize count_index variables, reducing the rank by count_index. */
3117 e->rank = rank - count_index;
3119 was_fullref = ar->type == AR_FULL;
3121 if (e->rank == 0)
3122 ar->type = AR_ELEMENT;
3123 else
3124 ar->type = AR_SECTION;
3126 /* Loop over the indices. For each index, create the expression
3127 index * stride + lbound(e, dim). */
3129 i_index = 0;
3130 for (i=0; i < ar->dimen; i++)
3132 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
3134 if (index[i_index] != NULL)
3136 gfc_expr *lbound, *nindex;
3137 gfc_expr *loopvar;
3139 loopvar = gfc_copy_expr (index[i_index]);
3141 if (ar->stride[i])
3143 gfc_expr *tmp;
3145 tmp = gfc_copy_expr(ar->stride[i]);
3146 if (tmp->ts.kind != gfc_index_integer_kind)
3148 gfc_typespec ts;
3149 gfc_clear_ts (&ts);
3150 ts.type = BT_INTEGER;
3151 ts.kind = gfc_index_integer_kind;
3152 gfc_convert_type (tmp, &ts, 2);
3154 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
3156 else
3157 nindex = loopvar;
3159 /* Calculate the lower bound of the expression. */
3160 if (ar->start[i])
3162 lbound = gfc_copy_expr (ar->start[i]);
3163 if (lbound->ts.kind != gfc_index_integer_kind)
3165 gfc_typespec ts;
3166 gfc_clear_ts (&ts);
3167 ts.type = BT_INTEGER;
3168 ts.kind = gfc_index_integer_kind;
3169 gfc_convert_type (lbound, &ts, 2);
3173 else
3175 gfc_expr *lbound_e;
3176 gfc_ref *ref;
3178 lbound_e = gfc_copy_expr (e_in);
3180 for (ref = lbound_e->ref; ref; ref = ref->next)
3181 if (ref->type == REF_ARRAY
3182 && (ref->u.ar.type == AR_FULL
3183 || ref->u.ar.type == AR_SECTION))
3184 break;
3186 if (ref->next)
3188 gfc_free_ref_list (ref->next);
3189 ref->next = NULL;
3192 if (!was_fullref)
3194 /* Look at full individual sections, like a(:). The first index
3195 is the lbound of a full ref. */
3196 int j;
3197 gfc_array_ref *ar;
3199 ar = &ref->u.ar;
3200 ar->type = AR_FULL;
3201 for (j = 0; j < ar->dimen; j++)
3203 gfc_free_expr (ar->start[j]);
3204 ar->start[j] = NULL;
3205 gfc_free_expr (ar->end[j]);
3206 ar->end[j] = NULL;
3207 gfc_free_expr (ar->stride[j]);
3208 ar->stride[j] = NULL;
3211 /* We have to get rid of the shape, if there is one. Do
3212 so by freeing it and calling gfc_resolve to rebuild
3213 it, if necessary. */
3215 if (lbound_e->shape)
3216 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
3218 lbound_e->rank = ar->dimen;
3219 gfc_resolve_expr (lbound_e);
3221 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
3222 i + 1);
3223 gfc_free_expr (lbound_e);
3226 ar->dimen_type[i] = DIMEN_ELEMENT;
3228 gfc_free_expr (ar->start[i]);
3229 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
3231 gfc_free_expr (ar->end[i]);
3232 ar->end[i] = NULL;
3233 gfc_free_expr (ar->stride[i]);
3234 ar->stride[i] = NULL;
3235 gfc_simplify_expr (ar->start[i], 0);
3237 else if (was_fullref)
3239 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
3241 i_index ++;
3245 return e;
3248 /* Helper function to check for a dimen vector as subscript. */
3250 static bool
3251 has_dimen_vector_ref (gfc_expr *e)
3253 gfc_array_ref *ar;
3254 int i;
3256 ar = gfc_find_array_ref (e);
3257 gcc_assert (ar);
3258 if (ar->type == AR_FULL)
3259 return false;
3261 for (i=0; i<ar->dimen; i++)
3262 if (ar->dimen_type[i] == DIMEN_VECTOR)
3263 return true;
3265 return false;
3268 /* If handed an expression of the form
3270 TRANSPOSE(CONJG(A))
3272 check if A can be handled by matmul and return if there is an uneven number
3273 of CONJG calls. Return a pointer to the array when everything is OK, NULL
3274 otherwise. The caller has to check for the correct rank. */
3276 static gfc_expr*
3277 check_conjg_transpose_variable (gfc_expr *e, bool *conjg, bool *transpose)
3279 *conjg = false;
3280 *transpose = false;
3284 if (e->expr_type == EXPR_VARIABLE)
3286 gcc_assert (e->rank == 1 || e->rank == 2);
3287 return e;
3289 else if (e->expr_type == EXPR_FUNCTION)
3291 if (e->value.function.isym == NULL)
3292 return NULL;
3294 if (e->value.function.isym->id == GFC_ISYM_CONJG)
3295 *conjg = !*conjg;
3296 else if (e->value.function.isym->id == GFC_ISYM_TRANSPOSE)
3297 *transpose = !*transpose;
3298 else return NULL;
3300 else
3301 return NULL;
3303 e = e->value.function.actual->expr;
3305 while(1);
3307 return NULL;
3310 /* Inline assignments of the form c = matmul(a,b).
3311 Handle only the cases currently where b and c are rank-two arrays.
3313 This basically translates the code to
3315 BLOCK
3316 integer i,j,k
3317 c = 0
3318 do j=0, size(b,2)-1
3319 do k=0, size(a, 2)-1
3320 do i=0, size(a, 1)-1
3321 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
3322 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
3323 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
3324 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
3325 end do
3326 end do
3327 end do
3328 END BLOCK
3332 static int
3333 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
3334 void *data ATTRIBUTE_UNUSED)
3336 gfc_code *co = *c;
3337 gfc_expr *expr1, *expr2;
3338 gfc_expr *matrix_a, *matrix_b;
3339 gfc_actual_arglist *a, *b;
3340 gfc_code *do_1, *do_2, *do_3, *assign_zero, *assign_matmul;
3341 gfc_expr *zero_e;
3342 gfc_expr *u1, *u2, *u3;
3343 gfc_expr *list[2];
3344 gfc_expr *ascalar, *bscalar, *cscalar;
3345 gfc_expr *mult;
3346 gfc_expr *var_1, *var_2, *var_3;
3347 gfc_expr *zero;
3348 gfc_namespace *ns;
3349 gfc_intrinsic_op op_times, op_plus;
3350 enum matrix_case m_case;
3351 int i;
3352 gfc_code *if_limit = NULL;
3353 gfc_code **next_code_point;
3354 bool conjg_a, conjg_b, transpose_a, transpose_b;
3356 if (co->op != EXEC_ASSIGN)
3357 return 0;
3359 if (in_where)
3360 return 0;
3362 /* The BLOCKS generated for the temporary variables and FORALL don't
3363 mix. */
3364 if (forall_level > 0)
3365 return 0;
3367 /* For now don't do anything in OpenMP workshare, it confuses
3368 its translation, which expects only the allowed statements in there.
3369 We should figure out how to parallelize this eventually. */
3370 if (in_omp_workshare)
3371 return 0;
3373 expr1 = co->expr1;
3374 expr2 = co->expr2;
3375 if (expr2->expr_type != EXPR_FUNCTION
3376 || expr2->value.function.isym == NULL
3377 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
3378 return 0;
3380 current_code = c;
3381 inserted_block = NULL;
3382 changed_statement = NULL;
3384 a = expr2->value.function.actual;
3385 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
3386 if (matrix_a == NULL)
3387 return 0;
3389 b = a->next;
3390 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
3391 if (matrix_b == NULL)
3392 return 0;
3394 if (has_dimen_vector_ref (expr1) || has_dimen_vector_ref (matrix_a)
3395 || has_dimen_vector_ref (matrix_b))
3396 return 0;
3398 /* We do not handle data dependencies yet. */
3399 if (gfc_check_dependency (expr1, matrix_a, true)
3400 || gfc_check_dependency (expr1, matrix_b, true))
3401 return 0;
3403 m_case = none;
3404 if (matrix_a->rank == 2)
3406 if (transpose_a)
3408 if (matrix_b->rank == 2 && !transpose_b)
3409 m_case = A2TB2;
3411 else
3413 if (matrix_b->rank == 1)
3414 m_case = A2B1;
3415 else /* matrix_b->rank == 2 */
3417 if (transpose_b)
3418 m_case = A2B2T;
3419 else
3420 m_case = A2B2;
3424 else /* matrix_a->rank == 1 */
3426 if (matrix_b->rank == 2)
3428 if (!transpose_b)
3429 m_case = A1B2;
3433 if (m_case == none)
3434 return 0;
3436 ns = insert_block ();
3438 /* Assign the type of the zero expression for initializing the resulting
3439 array, and the expression (+ and * for real, integer and complex;
3440 .and. and .or for logical. */
3442 switch(expr1->ts.type)
3444 case BT_INTEGER:
3445 zero_e = gfc_get_int_expr (expr1->ts.kind, &expr1->where, 0);
3446 op_times = INTRINSIC_TIMES;
3447 op_plus = INTRINSIC_PLUS;
3448 break;
3450 case BT_LOGICAL:
3451 op_times = INTRINSIC_AND;
3452 op_plus = INTRINSIC_OR;
3453 zero_e = gfc_get_logical_expr (expr1->ts.kind, &expr1->where,
3455 break;
3456 case BT_REAL:
3457 zero_e = gfc_get_constant_expr (BT_REAL, expr1->ts.kind,
3458 &expr1->where);
3459 mpfr_set_si (zero_e->value.real, 0, GFC_RND_MODE);
3460 op_times = INTRINSIC_TIMES;
3461 op_plus = INTRINSIC_PLUS;
3462 break;
3464 case BT_COMPLEX:
3465 zero_e = gfc_get_constant_expr (BT_COMPLEX, expr1->ts.kind,
3466 &expr1->where);
3467 mpc_set_si_si (zero_e->value.complex, 0, 0, GFC_RND_MODE);
3468 op_times = INTRINSIC_TIMES;
3469 op_plus = INTRINSIC_PLUS;
3471 break;
3473 default:
3474 gcc_unreachable();
3477 current_code = &ns->code;
3479 /* Freeze the references, keeping track of how many temporary variables were
3480 created. */
3481 n_vars = 0;
3482 freeze_references (matrix_a);
3483 freeze_references (matrix_b);
3484 freeze_references (expr1);
3486 if (n_vars == 0)
3487 next_code_point = current_code;
3488 else
3490 next_code_point = &ns->code;
3491 for (i=0; i<n_vars; i++)
3492 next_code_point = &(*next_code_point)->next;
3495 /* Take care of the inline flag. If the limit check evaluates to a
3496 constant, dead code elimination will eliminate the unneeded branch. */
3498 if (m_case == A2B2 && flag_inline_matmul_limit > 0)
3500 if_limit = inline_limit_check (matrix_a, matrix_b, m_case);
3502 /* Insert the original statement into the else branch. */
3503 if_limit->block->block->next = co;
3504 co->next = NULL;
3506 /* ... and the new ones go into the original one. */
3507 *next_code_point = if_limit;
3508 next_code_point = &if_limit->block->next;
3511 assign_zero = XCNEW (gfc_code);
3512 assign_zero->op = EXEC_ASSIGN;
3513 assign_zero->loc = co->loc;
3514 assign_zero->expr1 = gfc_copy_expr (expr1);
3515 assign_zero->expr2 = zero_e;
3517 /* Handle the reallocation, if needed. */
3518 if (flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1))
3520 gfc_code *lhs_alloc;
3522 /* Only need to check a single dimension for the A2B2 case for
3523 bounds checking, the rest will be allocated. Also check this
3524 for A2B1. */
3526 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && (m_case == A2B2 || m_case == A2B1))
3528 gfc_code *test;
3529 gfc_expr *a2, *b1;
3531 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3532 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3533 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
3534 "in MATMUL intrinsic: Is %ld, should be %ld");
3535 *next_code_point = test;
3536 next_code_point = &test->next;
3540 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
3542 *next_code_point = lhs_alloc;
3543 next_code_point = &lhs_alloc->next;
3546 else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3548 gfc_code *test;
3549 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
3551 if (m_case == A2B2 || m_case == A2B1)
3553 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3554 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3555 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
3556 "in MATMUL intrinsic: Is %ld, should be %ld");
3557 *next_code_point = test;
3558 next_code_point = &test->next;
3560 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3561 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3563 if (m_case == A2B2)
3564 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3565 "MATMUL intrinsic for dimension 1: "
3566 "is %ld, should be %ld");
3567 else if (m_case == A2B1)
3568 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3569 "MATMUL intrinsic: "
3570 "is %ld, should be %ld");
3573 *next_code_point = test;
3574 next_code_point = &test->next;
3576 else if (m_case == A1B2)
3578 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3579 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3580 test = runtime_error_ne (b1, a1, "Dimension of array B incorrect "
3581 "in MATMUL intrinsic: Is %ld, should be %ld");
3582 *next_code_point = test;
3583 next_code_point = &test->next;
3585 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3586 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3588 test = runtime_error_ne (c1, b2, "Incorrect extent in return array in "
3589 "MATMUL intrinsic: "
3590 "is %ld, should be %ld");
3592 *next_code_point = test;
3593 next_code_point = &test->next;
3596 if (m_case == A2B2)
3598 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
3599 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3600 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
3601 "MATMUL intrinsic for dimension 2: is %ld, should be %ld");
3603 *next_code_point = test;
3604 next_code_point = &test->next;
3607 if (m_case == A2B2T)
3609 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3610 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3611 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3612 "MATMUL intrinsic for dimension 1: "
3613 "is %ld, should be %ld");
3615 *next_code_point = test;
3616 next_code_point = &test->next;
3618 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
3619 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3620 test = runtime_error_ne (c2, b1, "Incorrect extent in return array in "
3621 "MATMUL intrinsic for dimension 2: "
3622 "is %ld, should be %ld");
3623 *next_code_point = test;
3624 next_code_point = &test->next;
3626 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3627 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3629 test = runtime_error_ne (b2, a2, "Incorrect extent in argument B in "
3630 "MATMUL intrnisic for dimension 2: "
3631 "is %ld, should be %ld");
3632 *next_code_point = test;
3633 next_code_point = &test->next;
3637 if (m_case == A2TB2)
3639 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3640 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3642 test = runtime_error_ne (c1, a2, "Incorrect extent in return array in "
3643 "MATMUL intrinsic for dimension 1: "
3644 "is %ld, should be %ld");
3646 *next_code_point = test;
3647 next_code_point = &test->next;
3649 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
3650 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3651 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
3652 "MATMUL intrinsic for dimension 2: "
3653 "is %ld, should be %ld");
3654 *next_code_point = test;
3655 next_code_point = &test->next;
3657 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3658 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3660 test = runtime_error_ne (b1, a1, "Incorrect extent in argument B in "
3661 "MATMUL intrnisic for dimension 2: "
3662 "is %ld, should be %ld");
3663 *next_code_point = test;
3664 next_code_point = &test->next;
3669 *next_code_point = assign_zero;
3671 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
3673 assign_matmul = XCNEW (gfc_code);
3674 assign_matmul->op = EXEC_ASSIGN;
3675 assign_matmul->loc = co->loc;
3677 /* Get the bounds for the loops, create them and create the scalarized
3678 expressions. */
3680 switch (m_case)
3682 case A2B2:
3683 inline_limit_check (matrix_a, matrix_b, m_case);
3685 u1 = get_size_m1 (matrix_b, 2);
3686 u2 = get_size_m1 (matrix_a, 2);
3687 u3 = get_size_m1 (matrix_a, 1);
3689 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3690 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3691 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
3693 do_1->block->next = do_2;
3694 do_2->block->next = do_3;
3695 do_3->block->next = assign_matmul;
3697 var_1 = do_1->ext.iterator->var;
3698 var_2 = do_2->ext.iterator->var;
3699 var_3 = do_3->ext.iterator->var;
3701 list[0] = var_3;
3702 list[1] = var_1;
3703 cscalar = scalarized_expr (co->expr1, list, 2);
3705 list[0] = var_3;
3706 list[1] = var_2;
3707 ascalar = scalarized_expr (matrix_a, list, 2);
3709 list[0] = var_2;
3710 list[1] = var_1;
3711 bscalar = scalarized_expr (matrix_b, list, 2);
3713 break;
3715 case A2B2T:
3716 inline_limit_check (matrix_a, matrix_b, m_case);
3718 u1 = get_size_m1 (matrix_b, 1);
3719 u2 = get_size_m1 (matrix_a, 2);
3720 u3 = get_size_m1 (matrix_a, 1);
3722 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3723 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3724 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
3726 do_1->block->next = do_2;
3727 do_2->block->next = do_3;
3728 do_3->block->next = assign_matmul;
3730 var_1 = do_1->ext.iterator->var;
3731 var_2 = do_2->ext.iterator->var;
3732 var_3 = do_3->ext.iterator->var;
3734 list[0] = var_3;
3735 list[1] = var_1;
3736 cscalar = scalarized_expr (co->expr1, list, 2);
3738 list[0] = var_3;
3739 list[1] = var_2;
3740 ascalar = scalarized_expr (matrix_a, list, 2);
3742 list[0] = var_1;
3743 list[1] = var_2;
3744 bscalar = scalarized_expr (matrix_b, list, 2);
3746 break;
3748 case A2TB2:
3749 inline_limit_check (matrix_a, matrix_b, m_case);
3751 u1 = get_size_m1 (matrix_a, 2);
3752 u2 = get_size_m1 (matrix_b, 2);
3753 u3 = get_size_m1 (matrix_a, 1);
3755 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3756 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3757 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
3759 do_1->block->next = do_2;
3760 do_2->block->next = do_3;
3761 do_3->block->next = assign_matmul;
3763 var_1 = do_1->ext.iterator->var;
3764 var_2 = do_2->ext.iterator->var;
3765 var_3 = do_3->ext.iterator->var;
3767 list[0] = var_1;
3768 list[1] = var_2;
3769 cscalar = scalarized_expr (co->expr1, list, 2);
3771 list[0] = var_3;
3772 list[1] = var_1;
3773 ascalar = scalarized_expr (matrix_a, list, 2);
3775 list[0] = var_3;
3776 list[1] = var_2;
3777 bscalar = scalarized_expr (matrix_b, list, 2);
3779 break;
3781 case A2B1:
3782 u1 = get_size_m1 (matrix_b, 1);
3783 u2 = get_size_m1 (matrix_a, 1);
3785 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3786 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3788 do_1->block->next = do_2;
3789 do_2->block->next = assign_matmul;
3791 var_1 = do_1->ext.iterator->var;
3792 var_2 = do_2->ext.iterator->var;
3794 list[0] = var_2;
3795 cscalar = scalarized_expr (co->expr1, list, 1);
3797 list[0] = var_2;
3798 list[1] = var_1;
3799 ascalar = scalarized_expr (matrix_a, list, 2);
3801 list[0] = var_1;
3802 bscalar = scalarized_expr (matrix_b, list, 1);
3804 break;
3806 case A1B2:
3807 u1 = get_size_m1 (matrix_b, 2);
3808 u2 = get_size_m1 (matrix_a, 1);
3810 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3811 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3813 do_1->block->next = do_2;
3814 do_2->block->next = assign_matmul;
3816 var_1 = do_1->ext.iterator->var;
3817 var_2 = do_2->ext.iterator->var;
3819 list[0] = var_1;
3820 cscalar = scalarized_expr (co->expr1, list, 1);
3822 list[0] = var_2;
3823 ascalar = scalarized_expr (matrix_a, list, 1);
3825 list[0] = var_2;
3826 list[1] = var_1;
3827 bscalar = scalarized_expr (matrix_b, list, 2);
3829 break;
3831 default:
3832 gcc_unreachable();
3835 if (conjg_a)
3836 ascalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
3837 matrix_a->where, 1, ascalar);
3839 if (conjg_b)
3840 bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
3841 matrix_b->where, 1, bscalar);
3843 /* First loop comes after the zero assignment. */
3844 assign_zero->next = do_1;
3846 /* Build the assignment expression in the loop. */
3847 assign_matmul->expr1 = gfc_copy_expr (cscalar);
3849 mult = get_operand (op_times, ascalar, bscalar);
3850 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
3852 /* If we don't want to keep the original statement around in
3853 the else branch, we can free it. */
3855 if (if_limit == NULL)
3856 gfc_free_statements(co);
3857 else
3858 co->next = NULL;
3860 gfc_free_expr (zero);
3861 *walk_subtrees = 0;
3862 return 0;
3865 #define WALK_SUBEXPR(NODE) \
3866 do \
3868 result = gfc_expr_walker (&(NODE), exprfn, data); \
3869 if (result) \
3870 return result; \
3872 while (0)
3873 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
3875 /* Walk expression *E, calling EXPRFN on each expression in it. */
3878 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
3880 while (*e)
3882 int walk_subtrees = 1;
3883 gfc_actual_arglist *a;
3884 gfc_ref *r;
3885 gfc_constructor *c;
3887 int result = exprfn (e, &walk_subtrees, data);
3888 if (result)
3889 return result;
3890 if (walk_subtrees)
3891 switch ((*e)->expr_type)
3893 case EXPR_OP:
3894 WALK_SUBEXPR ((*e)->value.op.op1);
3895 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
3896 break;
3897 case EXPR_FUNCTION:
3898 for (a = (*e)->value.function.actual; a; a = a->next)
3899 WALK_SUBEXPR (a->expr);
3900 break;
3901 case EXPR_COMPCALL:
3902 case EXPR_PPC:
3903 WALK_SUBEXPR ((*e)->value.compcall.base_object);
3904 for (a = (*e)->value.compcall.actual; a; a = a->next)
3905 WALK_SUBEXPR (a->expr);
3906 break;
3908 case EXPR_STRUCTURE:
3909 case EXPR_ARRAY:
3910 for (c = gfc_constructor_first ((*e)->value.constructor); c;
3911 c = gfc_constructor_next (c))
3913 if (c->iterator == NULL)
3914 WALK_SUBEXPR (c->expr);
3915 else
3917 iterator_level ++;
3918 WALK_SUBEXPR (c->expr);
3919 iterator_level --;
3920 WALK_SUBEXPR (c->iterator->var);
3921 WALK_SUBEXPR (c->iterator->start);
3922 WALK_SUBEXPR (c->iterator->end);
3923 WALK_SUBEXPR (c->iterator->step);
3927 if ((*e)->expr_type != EXPR_ARRAY)
3928 break;
3930 /* Fall through to the variable case in order to walk the
3931 reference. */
3932 gcc_fallthrough ();
3934 case EXPR_SUBSTRING:
3935 case EXPR_VARIABLE:
3936 for (r = (*e)->ref; r; r = r->next)
3938 gfc_array_ref *ar;
3939 int i;
3941 switch (r->type)
3943 case REF_ARRAY:
3944 ar = &r->u.ar;
3945 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
3947 for (i=0; i< ar->dimen; i++)
3949 WALK_SUBEXPR (ar->start[i]);
3950 WALK_SUBEXPR (ar->end[i]);
3951 WALK_SUBEXPR (ar->stride[i]);
3955 break;
3957 case REF_SUBSTRING:
3958 WALK_SUBEXPR (r->u.ss.start);
3959 WALK_SUBEXPR (r->u.ss.end);
3960 break;
3962 case REF_COMPONENT:
3963 break;
3967 default:
3968 break;
3970 return 0;
3972 return 0;
3975 #define WALK_SUBCODE(NODE) \
3976 do \
3978 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
3979 if (result) \
3980 return result; \
3982 while (0)
3984 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
3985 on each expression in it. If any of the hooks returns non-zero, that
3986 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
3987 no subcodes or subexpressions are traversed. */
3990 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
3991 void *data)
3993 for (; *c; c = &(*c)->next)
3995 int walk_subtrees = 1;
3996 int result = codefn (c, &walk_subtrees, data);
3997 if (result)
3998 return result;
4000 if (walk_subtrees)
4002 gfc_code *b;
4003 gfc_actual_arglist *a;
4004 gfc_code *co;
4005 gfc_association_list *alist;
4006 bool saved_in_omp_workshare;
4007 bool saved_in_where;
4009 /* There might be statement insertions before the current code,
4010 which must not affect the expression walker. */
4012 co = *c;
4013 saved_in_omp_workshare = in_omp_workshare;
4014 saved_in_where = in_where;
4016 switch (co->op)
4019 case EXEC_BLOCK:
4020 WALK_SUBCODE (co->ext.block.ns->code);
4021 if (co->ext.block.assoc)
4023 bool saved_in_assoc_list = in_assoc_list;
4025 in_assoc_list = true;
4026 for (alist = co->ext.block.assoc; alist; alist = alist->next)
4027 WALK_SUBEXPR (alist->target);
4029 in_assoc_list = saved_in_assoc_list;
4032 break;
4034 case EXEC_DO:
4035 doloop_level ++;
4036 WALK_SUBEXPR (co->ext.iterator->var);
4037 WALK_SUBEXPR (co->ext.iterator->start);
4038 WALK_SUBEXPR (co->ext.iterator->end);
4039 WALK_SUBEXPR (co->ext.iterator->step);
4040 break;
4042 case EXEC_WHERE:
4043 in_where = true;
4044 break;
4046 case EXEC_CALL:
4047 case EXEC_ASSIGN_CALL:
4048 for (a = co->ext.actual; a; a = a->next)
4049 WALK_SUBEXPR (a->expr);
4050 break;
4052 case EXEC_CALL_PPC:
4053 WALK_SUBEXPR (co->expr1);
4054 for (a = co->ext.actual; a; a = a->next)
4055 WALK_SUBEXPR (a->expr);
4056 break;
4058 case EXEC_SELECT:
4059 WALK_SUBEXPR (co->expr1);
4060 for (b = co->block; b; b = b->block)
4062 gfc_case *cp;
4063 for (cp = b->ext.block.case_list; cp; cp = cp->next)
4065 WALK_SUBEXPR (cp->low);
4066 WALK_SUBEXPR (cp->high);
4068 WALK_SUBCODE (b->next);
4070 continue;
4072 case EXEC_ALLOCATE:
4073 case EXEC_DEALLOCATE:
4075 gfc_alloc *a;
4076 for (a = co->ext.alloc.list; a; a = a->next)
4077 WALK_SUBEXPR (a->expr);
4078 break;
4081 case EXEC_FORALL:
4082 case EXEC_DO_CONCURRENT:
4084 gfc_forall_iterator *fa;
4085 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4087 WALK_SUBEXPR (fa->var);
4088 WALK_SUBEXPR (fa->start);
4089 WALK_SUBEXPR (fa->end);
4090 WALK_SUBEXPR (fa->stride);
4092 if (co->op == EXEC_FORALL)
4093 forall_level ++;
4094 break;
4097 case EXEC_OPEN:
4098 WALK_SUBEXPR (co->ext.open->unit);
4099 WALK_SUBEXPR (co->ext.open->file);
4100 WALK_SUBEXPR (co->ext.open->status);
4101 WALK_SUBEXPR (co->ext.open->access);
4102 WALK_SUBEXPR (co->ext.open->form);
4103 WALK_SUBEXPR (co->ext.open->recl);
4104 WALK_SUBEXPR (co->ext.open->blank);
4105 WALK_SUBEXPR (co->ext.open->position);
4106 WALK_SUBEXPR (co->ext.open->action);
4107 WALK_SUBEXPR (co->ext.open->delim);
4108 WALK_SUBEXPR (co->ext.open->pad);
4109 WALK_SUBEXPR (co->ext.open->iostat);
4110 WALK_SUBEXPR (co->ext.open->iomsg);
4111 WALK_SUBEXPR (co->ext.open->convert);
4112 WALK_SUBEXPR (co->ext.open->decimal);
4113 WALK_SUBEXPR (co->ext.open->encoding);
4114 WALK_SUBEXPR (co->ext.open->round);
4115 WALK_SUBEXPR (co->ext.open->sign);
4116 WALK_SUBEXPR (co->ext.open->asynchronous);
4117 WALK_SUBEXPR (co->ext.open->id);
4118 WALK_SUBEXPR (co->ext.open->newunit);
4119 WALK_SUBEXPR (co->ext.open->share);
4120 WALK_SUBEXPR (co->ext.open->cc);
4121 break;
4123 case EXEC_CLOSE:
4124 WALK_SUBEXPR (co->ext.close->unit);
4125 WALK_SUBEXPR (co->ext.close->status);
4126 WALK_SUBEXPR (co->ext.close->iostat);
4127 WALK_SUBEXPR (co->ext.close->iomsg);
4128 break;
4130 case EXEC_BACKSPACE:
4131 case EXEC_ENDFILE:
4132 case EXEC_REWIND:
4133 case EXEC_FLUSH:
4134 WALK_SUBEXPR (co->ext.filepos->unit);
4135 WALK_SUBEXPR (co->ext.filepos->iostat);
4136 WALK_SUBEXPR (co->ext.filepos->iomsg);
4137 break;
4139 case EXEC_INQUIRE:
4140 WALK_SUBEXPR (co->ext.inquire->unit);
4141 WALK_SUBEXPR (co->ext.inquire->file);
4142 WALK_SUBEXPR (co->ext.inquire->iomsg);
4143 WALK_SUBEXPR (co->ext.inquire->iostat);
4144 WALK_SUBEXPR (co->ext.inquire->exist);
4145 WALK_SUBEXPR (co->ext.inquire->opened);
4146 WALK_SUBEXPR (co->ext.inquire->number);
4147 WALK_SUBEXPR (co->ext.inquire->named);
4148 WALK_SUBEXPR (co->ext.inquire->name);
4149 WALK_SUBEXPR (co->ext.inquire->access);
4150 WALK_SUBEXPR (co->ext.inquire->sequential);
4151 WALK_SUBEXPR (co->ext.inquire->direct);
4152 WALK_SUBEXPR (co->ext.inquire->form);
4153 WALK_SUBEXPR (co->ext.inquire->formatted);
4154 WALK_SUBEXPR (co->ext.inquire->unformatted);
4155 WALK_SUBEXPR (co->ext.inquire->recl);
4156 WALK_SUBEXPR (co->ext.inquire->nextrec);
4157 WALK_SUBEXPR (co->ext.inquire->blank);
4158 WALK_SUBEXPR (co->ext.inquire->position);
4159 WALK_SUBEXPR (co->ext.inquire->action);
4160 WALK_SUBEXPR (co->ext.inquire->read);
4161 WALK_SUBEXPR (co->ext.inquire->write);
4162 WALK_SUBEXPR (co->ext.inquire->readwrite);
4163 WALK_SUBEXPR (co->ext.inquire->delim);
4164 WALK_SUBEXPR (co->ext.inquire->encoding);
4165 WALK_SUBEXPR (co->ext.inquire->pad);
4166 WALK_SUBEXPR (co->ext.inquire->iolength);
4167 WALK_SUBEXPR (co->ext.inquire->convert);
4168 WALK_SUBEXPR (co->ext.inquire->strm_pos);
4169 WALK_SUBEXPR (co->ext.inquire->asynchronous);
4170 WALK_SUBEXPR (co->ext.inquire->decimal);
4171 WALK_SUBEXPR (co->ext.inquire->pending);
4172 WALK_SUBEXPR (co->ext.inquire->id);
4173 WALK_SUBEXPR (co->ext.inquire->sign);
4174 WALK_SUBEXPR (co->ext.inquire->size);
4175 WALK_SUBEXPR (co->ext.inquire->round);
4176 break;
4178 case EXEC_WAIT:
4179 WALK_SUBEXPR (co->ext.wait->unit);
4180 WALK_SUBEXPR (co->ext.wait->iostat);
4181 WALK_SUBEXPR (co->ext.wait->iomsg);
4182 WALK_SUBEXPR (co->ext.wait->id);
4183 break;
4185 case EXEC_READ:
4186 case EXEC_WRITE:
4187 WALK_SUBEXPR (co->ext.dt->io_unit);
4188 WALK_SUBEXPR (co->ext.dt->format_expr);
4189 WALK_SUBEXPR (co->ext.dt->rec);
4190 WALK_SUBEXPR (co->ext.dt->advance);
4191 WALK_SUBEXPR (co->ext.dt->iostat);
4192 WALK_SUBEXPR (co->ext.dt->size);
4193 WALK_SUBEXPR (co->ext.dt->iomsg);
4194 WALK_SUBEXPR (co->ext.dt->id);
4195 WALK_SUBEXPR (co->ext.dt->pos);
4196 WALK_SUBEXPR (co->ext.dt->asynchronous);
4197 WALK_SUBEXPR (co->ext.dt->blank);
4198 WALK_SUBEXPR (co->ext.dt->decimal);
4199 WALK_SUBEXPR (co->ext.dt->delim);
4200 WALK_SUBEXPR (co->ext.dt->pad);
4201 WALK_SUBEXPR (co->ext.dt->round);
4202 WALK_SUBEXPR (co->ext.dt->sign);
4203 WALK_SUBEXPR (co->ext.dt->extra_comma);
4204 break;
4206 case EXEC_OMP_PARALLEL:
4207 case EXEC_OMP_PARALLEL_DO:
4208 case EXEC_OMP_PARALLEL_DO_SIMD:
4209 case EXEC_OMP_PARALLEL_SECTIONS:
4211 in_omp_workshare = false;
4213 /* This goto serves as a shortcut to avoid code
4214 duplication or a larger if or switch statement. */
4215 goto check_omp_clauses;
4217 case EXEC_OMP_WORKSHARE:
4218 case EXEC_OMP_PARALLEL_WORKSHARE:
4220 in_omp_workshare = true;
4222 /* Fall through */
4224 case EXEC_OMP_CRITICAL:
4225 case EXEC_OMP_DISTRIBUTE:
4226 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
4227 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
4228 case EXEC_OMP_DISTRIBUTE_SIMD:
4229 case EXEC_OMP_DO:
4230 case EXEC_OMP_DO_SIMD:
4231 case EXEC_OMP_ORDERED:
4232 case EXEC_OMP_SECTIONS:
4233 case EXEC_OMP_SINGLE:
4234 case EXEC_OMP_END_SINGLE:
4235 case EXEC_OMP_SIMD:
4236 case EXEC_OMP_TASKLOOP:
4237 case EXEC_OMP_TASKLOOP_SIMD:
4238 case EXEC_OMP_TARGET:
4239 case EXEC_OMP_TARGET_DATA:
4240 case EXEC_OMP_TARGET_ENTER_DATA:
4241 case EXEC_OMP_TARGET_EXIT_DATA:
4242 case EXEC_OMP_TARGET_PARALLEL:
4243 case EXEC_OMP_TARGET_PARALLEL_DO:
4244 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
4245 case EXEC_OMP_TARGET_SIMD:
4246 case EXEC_OMP_TARGET_TEAMS:
4247 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4248 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
4249 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4250 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
4251 case EXEC_OMP_TARGET_UPDATE:
4252 case EXEC_OMP_TASK:
4253 case EXEC_OMP_TEAMS:
4254 case EXEC_OMP_TEAMS_DISTRIBUTE:
4255 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
4256 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4257 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
4259 /* Come to this label only from the
4260 EXEC_OMP_PARALLEL_* cases above. */
4262 check_omp_clauses:
4264 if (co->ext.omp_clauses)
4266 gfc_omp_namelist *n;
4267 static int list_types[]
4268 = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
4269 OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
4270 size_t idx;
4271 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
4272 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
4273 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
4274 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
4275 WALK_SUBEXPR (co->ext.omp_clauses->safelen_expr);
4276 WALK_SUBEXPR (co->ext.omp_clauses->simdlen_expr);
4277 WALK_SUBEXPR (co->ext.omp_clauses->num_teams);
4278 WALK_SUBEXPR (co->ext.omp_clauses->device);
4279 WALK_SUBEXPR (co->ext.omp_clauses->thread_limit);
4280 WALK_SUBEXPR (co->ext.omp_clauses->dist_chunk_size);
4281 WALK_SUBEXPR (co->ext.omp_clauses->grainsize);
4282 WALK_SUBEXPR (co->ext.omp_clauses->hint);
4283 WALK_SUBEXPR (co->ext.omp_clauses->num_tasks);
4284 WALK_SUBEXPR (co->ext.omp_clauses->priority);
4285 for (idx = 0; idx < OMP_IF_LAST; idx++)
4286 WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
4287 for (idx = 0;
4288 idx < sizeof (list_types) / sizeof (list_types[0]);
4289 idx++)
4290 for (n = co->ext.omp_clauses->lists[list_types[idx]];
4291 n; n = n->next)
4292 WALK_SUBEXPR (n->expr);
4294 break;
4295 default:
4296 break;
4299 WALK_SUBEXPR (co->expr1);
4300 WALK_SUBEXPR (co->expr2);
4301 WALK_SUBEXPR (co->expr3);
4302 WALK_SUBEXPR (co->expr4);
4303 for (b = co->block; b; b = b->block)
4305 WALK_SUBEXPR (b->expr1);
4306 WALK_SUBEXPR (b->expr2);
4307 WALK_SUBCODE (b->next);
4310 if (co->op == EXEC_FORALL)
4311 forall_level --;
4313 if (co->op == EXEC_DO)
4314 doloop_level --;
4316 in_omp_workshare = saved_in_omp_workshare;
4317 in_where = saved_in_where;
4320 return 0;