PR rtl-optimization/82913
[official-gcc.git] / gcc / fortran / frontend-passes.c
blobb3db18ac5f1c371cdecefd4acbc3689e182eae9e
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 int do_intent (gfc_expr **);
43 static int do_subscript (gfc_expr **);
44 static void optimize_reduction (gfc_namespace *);
45 static int callback_reduction (gfc_expr **, int *, void *);
46 static void realloc_strings (gfc_namespace *);
47 static gfc_expr *create_var (gfc_expr *, const char *vname=NULL);
48 static int matmul_to_var_expr (gfc_expr **, int *, void *);
49 static int matmul_to_var_code (gfc_code **, int *, void *);
50 static int inline_matmul_assign (gfc_code **, int *, void *);
51 static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *,
52 locus *, gfc_namespace *,
53 char *vname=NULL);
54 static gfc_expr* check_conjg_transpose_variable (gfc_expr *, bool *,
55 bool *);
56 static bool has_dimen_vector_ref (gfc_expr *);
57 static int matmul_temp_args (gfc_code **, int *,void *data);
58 static int index_interchange (gfc_code **, int*, void *);
60 #ifdef CHECKING_P
61 static void check_locus (gfc_namespace *);
62 #endif
64 /* How deep we are inside an argument list. */
66 static int count_arglist;
68 /* Vector of gfc_expr ** we operate on. */
70 static vec<gfc_expr **> expr_array;
72 /* Pointer to the gfc_code we currently work on - to be able to insert
73 a block before the statement. */
75 static gfc_code **current_code;
77 /* Pointer to the block to be inserted, and the statement we are
78 changing within the block. */
80 static gfc_code *inserted_block, **changed_statement;
82 /* The namespace we are currently dealing with. */
84 static gfc_namespace *current_ns;
86 /* If we are within any forall loop. */
88 static int forall_level;
90 /* Keep track of whether we are within an OMP workshare. */
92 static bool in_omp_workshare;
94 /* Keep track of whether we are within a WHERE statement. */
96 static bool in_where;
98 /* Keep track of iterators for array constructors. */
100 static int iterator_level;
102 /* Keep track of DO loop levels. */
104 typedef struct {
105 gfc_code *c;
106 int branch_level;
107 bool seen_goto;
108 } do_t;
110 static vec<do_t> doloop_list;
111 static int doloop_level;
113 /* Keep track of if and select case levels. */
115 static int if_level;
116 static int select_level;
118 /* Vector of gfc_expr * to keep track of DO loops. */
120 struct my_struct *evec;
122 /* Keep track of association lists. */
124 static bool in_assoc_list;
126 /* Counter for temporary variables. */
128 static int var_num = 1;
130 /* What sort of matrix we are dealing with when inlining MATMUL. */
132 enum matrix_case { none=0, A2B2, A2B1, A1B2, A2B2T, A2TB2 };
134 /* Keep track of the number of expressions we have inserted so far
135 using create_var. */
137 int n_vars;
139 /* Entry point - run all passes for a namespace. */
141 void
142 gfc_run_passes (gfc_namespace *ns)
145 /* Warn about dubious DO loops where the index might
146 change. */
148 doloop_level = 0;
149 if_level = 0;
150 select_level = 0;
151 doloop_warn (ns);
152 doloop_list.release ();
153 int w, e;
155 #ifdef CHECKING_P
156 check_locus (ns);
157 #endif
159 if (flag_frontend_optimize || flag_frontend_loop_interchange)
160 optimize_namespace (ns);
162 if (flag_frontend_optimize)
164 optimize_reduction (ns);
165 if (flag_dump_fortran_optimized)
166 gfc_dump_parse_tree (ns, stdout);
168 expr_array.release ();
171 gfc_get_errors (&w, &e);
172 if (e > 0)
173 return;
175 if (flag_realloc_lhs)
176 realloc_strings (ns);
179 #ifdef CHECKING_P
181 /* Callback function: Warn if there is no location information in a
182 statement. */
184 static int
185 check_locus_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
186 void *data ATTRIBUTE_UNUSED)
188 current_code = c;
189 if (c && *c && (((*c)->loc.nextc == NULL) || ((*c)->loc.lb == NULL)))
190 gfc_warning_internal (0, "No location in statement");
192 return 0;
196 /* Callback function: Warn if there is no location information in an
197 expression. */
199 static int
200 check_locus_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
201 void *data ATTRIBUTE_UNUSED)
204 if (e && *e && (((*e)->where.nextc == NULL || (*e)->where.lb == NULL)))
205 gfc_warning_internal (0, "No location in expression near %L",
206 &((*current_code)->loc));
207 return 0;
210 /* Run check for missing location information. */
212 static void
213 check_locus (gfc_namespace *ns)
215 gfc_code_walker (&ns->code, check_locus_code, check_locus_expr, NULL);
217 for (ns = ns->contained; ns; ns = ns->sibling)
219 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
220 check_locus (ns);
224 #endif
226 /* Callback for each gfc_code node invoked from check_realloc_strings.
227 For an allocatable LHS string which also appears as a variable on
228 the RHS, replace
230 a = a(x:y)
232 with
234 tmp = a(x:y)
235 a = tmp
238 static int
239 realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
240 void *data ATTRIBUTE_UNUSED)
242 gfc_expr *expr1, *expr2;
243 gfc_code *co = *c;
244 gfc_expr *n;
245 gfc_ref *ref;
246 bool found_substr;
248 if (co->op != EXEC_ASSIGN)
249 return 0;
251 expr1 = co->expr1;
252 if (expr1->ts.type != BT_CHARACTER || expr1->rank != 0
253 || !gfc_expr_attr(expr1).allocatable
254 || !expr1->ts.deferred)
255 return 0;
257 expr2 = gfc_discard_nops (co->expr2);
259 if (expr2->expr_type == EXPR_VARIABLE)
261 found_substr = false;
262 for (ref = expr2->ref; ref; ref = ref->next)
264 if (ref->type == REF_SUBSTRING)
266 found_substr = true;
267 break;
270 if (!found_substr)
271 return 0;
273 else if (expr2->expr_type != EXPR_OP
274 || expr2->value.op.op != INTRINSIC_CONCAT)
275 return 0;
277 if (!gfc_check_dependency (expr1, expr2, true))
278 return 0;
280 /* gfc_check_dependency doesn't always pick up identical expressions.
281 However, eliminating the above sends the compiler into an infinite
282 loop on valid expressions. Without this check, the gimplifier emits
283 an ICE for a = a, where a is deferred character length. */
284 if (!gfc_dep_compare_expr (expr1, expr2))
285 return 0;
287 current_code = c;
288 inserted_block = NULL;
289 changed_statement = NULL;
290 n = create_var (expr2, "realloc_string");
291 co->expr2 = n;
292 return 0;
295 /* Callback for each gfc_code node invoked through gfc_code_walker
296 from optimize_namespace. */
298 static int
299 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
300 void *data ATTRIBUTE_UNUSED)
303 gfc_exec_op op;
305 op = (*c)->op;
307 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
308 || op == EXEC_CALL_PPC)
309 count_arglist = 1;
310 else
311 count_arglist = 0;
313 current_code = c;
314 inserted_block = NULL;
315 changed_statement = NULL;
317 if (op == EXEC_ASSIGN)
318 optimize_assignment (*c);
319 return 0;
322 /* Callback for each gfc_expr node invoked through gfc_code_walker
323 from optimize_namespace. */
325 static int
326 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
327 void *data ATTRIBUTE_UNUSED)
329 bool function_expr;
331 if ((*e)->expr_type == EXPR_FUNCTION)
333 count_arglist ++;
334 function_expr = true;
336 else
337 function_expr = false;
339 if (optimize_trim (*e))
340 gfc_simplify_expr (*e, 0);
342 if (optimize_lexical_comparison (*e))
343 gfc_simplify_expr (*e, 0);
345 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
346 gfc_simplify_expr (*e, 0);
348 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
349 switch ((*e)->value.function.isym->id)
351 case GFC_ISYM_MINLOC:
352 case GFC_ISYM_MAXLOC:
353 optimize_minmaxloc (e);
354 break;
355 default:
356 break;
359 if (function_expr)
360 count_arglist --;
362 return 0;
365 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
366 function is a scalar, just copy it; otherwise returns the new element, the
367 old one can be freed. */
369 static gfc_expr *
370 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
372 gfc_expr *fcn, *e = c->expr;
374 fcn = gfc_copy_expr (e);
375 if (c->iterator)
377 gfc_constructor_base newbase;
378 gfc_expr *new_expr;
379 gfc_constructor *new_c;
381 newbase = NULL;
382 new_expr = gfc_get_expr ();
383 new_expr->expr_type = EXPR_ARRAY;
384 new_expr->ts = e->ts;
385 new_expr->where = e->where;
386 new_expr->rank = 1;
387 new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
388 new_c->iterator = c->iterator;
389 new_expr->value.constructor = newbase;
390 c->iterator = NULL;
392 fcn = new_expr;
395 if (fcn->rank != 0)
397 gfc_isym_id id = fn->value.function.isym->id;
399 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
400 fcn = gfc_build_intrinsic_call (current_ns, id,
401 fn->value.function.isym->name,
402 fn->where, 3, fcn, NULL, NULL);
403 else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
404 fcn = gfc_build_intrinsic_call (current_ns, id,
405 fn->value.function.isym->name,
406 fn->where, 2, fcn, NULL);
407 else
408 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
410 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
413 return fcn;
416 /* Callback function for optimzation of reductions to scalars. Transform ANY
417 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
418 correspondingly. Handly only the simple cases without MASK and DIM. */
420 static int
421 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
422 void *data ATTRIBUTE_UNUSED)
424 gfc_expr *fn, *arg;
425 gfc_intrinsic_op op;
426 gfc_isym_id id;
427 gfc_actual_arglist *a;
428 gfc_actual_arglist *dim;
429 gfc_constructor *c;
430 gfc_expr *res, *new_expr;
431 gfc_actual_arglist *mask;
433 fn = *e;
435 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
436 || fn->value.function.isym == NULL)
437 return 0;
439 id = fn->value.function.isym->id;
441 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
442 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
443 return 0;
445 a = fn->value.function.actual;
447 /* Don't handle MASK or DIM. */
449 dim = a->next;
451 if (dim->expr != NULL)
452 return 0;
454 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
456 mask = dim->next;
457 if ( mask->expr != NULL)
458 return 0;
461 arg = a->expr;
463 if (arg->expr_type != EXPR_ARRAY)
464 return 0;
466 switch (id)
468 case GFC_ISYM_SUM:
469 op = INTRINSIC_PLUS;
470 break;
472 case GFC_ISYM_PRODUCT:
473 op = INTRINSIC_TIMES;
474 break;
476 case GFC_ISYM_ANY:
477 op = INTRINSIC_OR;
478 break;
480 case GFC_ISYM_ALL:
481 op = INTRINSIC_AND;
482 break;
484 default:
485 return 0;
488 c = gfc_constructor_first (arg->value.constructor);
490 /* Don't do any simplififcation if we have
491 - no element in the constructor or
492 - only have a single element in the array which contains an
493 iterator. */
495 if (c == NULL)
496 return 0;
498 res = copy_walk_reduction_arg (c, fn);
500 c = gfc_constructor_next (c);
501 while (c)
503 new_expr = gfc_get_expr ();
504 new_expr->ts = fn->ts;
505 new_expr->expr_type = EXPR_OP;
506 new_expr->rank = fn->rank;
507 new_expr->where = fn->where;
508 new_expr->value.op.op = op;
509 new_expr->value.op.op1 = res;
510 new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
511 res = new_expr;
512 c = gfc_constructor_next (c);
515 gfc_simplify_expr (res, 0);
516 *e = res;
517 gfc_free_expr (fn);
519 return 0;
522 /* Callback function for common function elimination, called from cfe_expr_0.
523 Put all eligible function expressions into expr_array. */
525 static int
526 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
527 void *data ATTRIBUTE_UNUSED)
530 if ((*e)->expr_type != EXPR_FUNCTION)
531 return 0;
533 /* We don't do character functions with unknown charlens. */
534 if ((*e)->ts.type == BT_CHARACTER
535 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
536 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
537 return 0;
539 /* We don't do function elimination within FORALL statements, it can
540 lead to wrong-code in certain circumstances. */
542 if (forall_level > 0)
543 return 0;
545 /* Function elimination inside an iterator could lead to functions which
546 depend on iterator variables being moved outside. FIXME: We should check
547 if the functions do indeed depend on the iterator variable. */
549 if (iterator_level > 0)
550 return 0;
552 /* If we don't know the shape at compile time, we create an allocatable
553 temporary variable to hold the intermediate result, but only if
554 allocation on assignment is active. */
556 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
557 return 0;
559 /* Skip the test for pure functions if -faggressive-function-elimination
560 is specified. */
561 if ((*e)->value.function.esym)
563 /* Don't create an array temporary for elemental functions. */
564 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
565 return 0;
567 /* Only eliminate potentially impure functions if the
568 user specifically requested it. */
569 if (!flag_aggressive_function_elimination
570 && !(*e)->value.function.esym->attr.pure
571 && !(*e)->value.function.esym->attr.implicit_pure)
572 return 0;
575 if ((*e)->value.function.isym)
577 /* Conversions are handled on the fly by the middle end,
578 transpose during trans-* stages and TRANSFER by the middle end. */
579 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
580 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
581 || gfc_inline_intrinsic_function_p (*e))
582 return 0;
584 /* Don't create an array temporary for elemental functions,
585 as this would be wasteful of memory.
586 FIXME: Create a scalar temporary during scalarization. */
587 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
588 return 0;
590 if (!(*e)->value.function.isym->pure)
591 return 0;
594 expr_array.safe_push (e);
595 return 0;
598 /* Auxiliary function to check if an expression is a temporary created by
599 create var. */
601 static bool
602 is_fe_temp (gfc_expr *e)
604 if (e->expr_type != EXPR_VARIABLE)
605 return false;
607 return e->symtree->n.sym->attr.fe_temp;
610 /* Determine the length of a string, if it can be evaluated as a constant
611 expression. Return a newly allocated gfc_expr or NULL on failure.
612 If the user specified a substring which is potentially longer than
613 the string itself, the string will be padded with spaces, which
614 is harmless. */
616 static gfc_expr *
617 constant_string_length (gfc_expr *e)
620 gfc_expr *length;
621 gfc_ref *ref;
622 gfc_expr *res;
623 mpz_t value;
625 if (e->ts.u.cl)
627 length = e->ts.u.cl->length;
628 if (length && length->expr_type == EXPR_CONSTANT)
629 return gfc_copy_expr(length);
632 /* Return length of substring, if constant. */
633 for (ref = e->ref; ref; ref = ref->next)
635 if (ref->type == REF_SUBSTRING
636 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
638 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
639 &e->where);
641 mpz_add_ui (res->value.integer, value, 1);
642 mpz_clear (value);
643 return res;
647 /* Return length of char symbol, if constant. */
649 if (e->symtree && e->symtree->n.sym->ts.u.cl
650 && e->symtree->n.sym->ts.u.cl->length
651 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
652 return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length);
654 return NULL;
658 /* Insert a block at the current position unless it has already
659 been inserted; in this case use the one already there. */
661 static gfc_namespace*
662 insert_block ()
664 gfc_namespace *ns;
666 /* If the block hasn't already been created, do so. */
667 if (inserted_block == NULL)
669 inserted_block = XCNEW (gfc_code);
670 inserted_block->op = EXEC_BLOCK;
671 inserted_block->loc = (*current_code)->loc;
672 ns = gfc_build_block_ns (current_ns);
673 inserted_block->ext.block.ns = ns;
674 inserted_block->ext.block.assoc = NULL;
676 ns->code = *current_code;
678 /* If the statement has a label, make sure it is transferred to
679 the newly created block. */
681 if ((*current_code)->here)
683 inserted_block->here = (*current_code)->here;
684 (*current_code)->here = NULL;
687 inserted_block->next = (*current_code)->next;
688 changed_statement = &(inserted_block->ext.block.ns->code);
689 (*current_code)->next = NULL;
690 /* Insert the BLOCK at the right position. */
691 *current_code = inserted_block;
692 ns->parent = current_ns;
694 else
695 ns = inserted_block->ext.block.ns;
697 return ns;
700 /* Returns a new expression (a variable) to be used in place of the old one,
701 with an optional assignment statement before the current statement to set
702 the value of the variable. Creates a new BLOCK for the statement if that
703 hasn't already been done and puts the statement, plus the newly created
704 variables, in that block. Special cases: If the expression is constant or
705 a temporary which has already been created, just copy it. */
707 static gfc_expr*
708 create_var (gfc_expr * e, const char *vname)
710 char name[GFC_MAX_SYMBOL_LEN +1];
711 gfc_symtree *symtree;
712 gfc_symbol *symbol;
713 gfc_expr *result;
714 gfc_code *n;
715 gfc_namespace *ns;
716 int i;
717 bool deferred;
719 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
720 return gfc_copy_expr (e);
722 ns = insert_block ();
724 if (vname)
725 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d_%s", var_num++, vname);
726 else
727 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d", var_num++);
729 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
730 gcc_unreachable ();
732 symbol = symtree->n.sym;
733 symbol->ts = e->ts;
735 if (e->rank > 0)
737 symbol->as = gfc_get_array_spec ();
738 symbol->as->rank = e->rank;
740 if (e->shape == NULL)
742 /* We don't know the shape at compile time, so we use an
743 allocatable. */
744 symbol->as->type = AS_DEFERRED;
745 symbol->attr.allocatable = 1;
747 else
749 symbol->as->type = AS_EXPLICIT;
750 /* Copy the shape. */
751 for (i=0; i<e->rank; i++)
753 gfc_expr *p, *q;
755 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
756 &(e->where));
757 mpz_set_si (p->value.integer, 1);
758 symbol->as->lower[i] = p;
760 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
761 &(e->where));
762 mpz_set (q->value.integer, e->shape[i]);
763 symbol->as->upper[i] = q;
768 deferred = 0;
769 if (e->ts.type == BT_CHARACTER && e->rank == 0)
771 gfc_expr *length;
773 symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
774 length = constant_string_length (e);
775 if (length)
776 symbol->ts.u.cl->length = length;
777 else
779 symbol->attr.allocatable = 1;
780 deferred = 1;
784 symbol->attr.flavor = FL_VARIABLE;
785 symbol->attr.referenced = 1;
786 symbol->attr.dimension = e->rank > 0;
787 symbol->attr.fe_temp = 1;
788 gfc_commit_symbol (symbol);
790 result = gfc_get_expr ();
791 result->expr_type = EXPR_VARIABLE;
792 result->ts = e->ts;
793 result->ts.deferred = deferred;
794 result->rank = e->rank;
795 result->shape = gfc_copy_shape (e->shape, e->rank);
796 result->symtree = symtree;
797 result->where = e->where;
798 if (e->rank > 0)
800 result->ref = gfc_get_ref ();
801 result->ref->type = REF_ARRAY;
802 result->ref->u.ar.type = AR_FULL;
803 result->ref->u.ar.where = e->where;
804 result->ref->u.ar.dimen = e->rank;
805 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
806 ? CLASS_DATA (symbol)->as : symbol->as;
807 if (warn_array_temporaries)
808 gfc_warning (OPT_Warray_temporaries,
809 "Creating array temporary at %L", &(e->where));
812 /* Generate the new assignment. */
813 n = XCNEW (gfc_code);
814 n->op = EXEC_ASSIGN;
815 n->loc = (*current_code)->loc;
816 n->next = *changed_statement;
817 n->expr1 = gfc_copy_expr (result);
818 n->expr2 = e;
819 *changed_statement = n;
820 n_vars ++;
822 return result;
825 /* Warn about function elimination. */
827 static void
828 do_warn_function_elimination (gfc_expr *e)
830 if (e->expr_type != EXPR_FUNCTION)
831 return;
832 if (e->value.function.esym)
833 gfc_warning (OPT_Wfunction_elimination,
834 "Removing call to function %qs at %L",
835 e->value.function.esym->name, &(e->where));
836 else if (e->value.function.isym)
837 gfc_warning (OPT_Wfunction_elimination,
838 "Removing call to function %qs at %L",
839 e->value.function.isym->name, &(e->where));
841 /* Callback function for the code walker for doing common function
842 elimination. This builds up the list of functions in the expression
843 and goes through them to detect duplicates, which it then replaces
844 by variables. */
846 static int
847 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
848 void *data ATTRIBUTE_UNUSED)
850 int i,j;
851 gfc_expr *newvar;
852 gfc_expr **ei, **ej;
854 /* Don't do this optimization within OMP workshare or ASSOC lists. */
856 if (in_omp_workshare || in_assoc_list)
858 *walk_subtrees = 0;
859 return 0;
862 expr_array.release ();
864 gfc_expr_walker (e, cfe_register_funcs, NULL);
866 /* Walk through all the functions. */
868 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
870 /* Skip if the function has been replaced by a variable already. */
871 if ((*ei)->expr_type == EXPR_VARIABLE)
872 continue;
874 newvar = NULL;
875 for (j=0; j<i; j++)
877 ej = expr_array[j];
878 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
880 if (newvar == NULL)
881 newvar = create_var (*ei, "fcn");
883 if (warn_function_elimination)
884 do_warn_function_elimination (*ej);
886 free (*ej);
887 *ej = gfc_copy_expr (newvar);
890 if (newvar)
891 *ei = newvar;
894 /* We did all the necessary walking in this function. */
895 *walk_subtrees = 0;
896 return 0;
899 /* Callback function for common function elimination, called from
900 gfc_code_walker. This keeps track of the current code, in order
901 to insert statements as needed. */
903 static int
904 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
906 current_code = c;
907 inserted_block = NULL;
908 changed_statement = NULL;
910 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
911 and allocation on assigment are prohibited inside WHERE, and finally
912 masking an expression would lead to wrong-code when replacing
914 WHERE (a>0)
915 b = sum(foo(a) + foo(a))
916 END WHERE
918 with
920 WHERE (a > 0)
921 tmp = foo(a)
922 b = sum(tmp + tmp)
923 END WHERE
926 if ((*c)->op == EXEC_WHERE)
928 *walk_subtrees = 0;
929 return 0;
933 return 0;
936 /* Dummy function for expression call back, for use when we
937 really don't want to do any walking. */
939 static int
940 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
941 void *data ATTRIBUTE_UNUSED)
943 *walk_subtrees = 0;
944 return 0;
947 /* Dummy function for code callback, for use when we really
948 don't want to do anything. */
950 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
951 int *walk_subtrees ATTRIBUTE_UNUSED,
952 void *data ATTRIBUTE_UNUSED)
954 return 0;
957 /* Code callback function for converting
958 do while(a)
959 end do
960 into the equivalent
962 if (.not. a) exit
963 end do
964 This is because common function elimination would otherwise place the
965 temporary variables outside the loop. */
967 static int
968 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
969 void *data ATTRIBUTE_UNUSED)
971 gfc_code *co = *c;
972 gfc_code *c_if1, *c_if2, *c_exit;
973 gfc_code *loopblock;
974 gfc_expr *e_not, *e_cond;
976 if (co->op != EXEC_DO_WHILE)
977 return 0;
979 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
980 return 0;
982 e_cond = co->expr1;
984 /* Generate the condition of the if statement, which is .not. the original
985 statement. */
986 e_not = gfc_get_expr ();
987 e_not->ts = e_cond->ts;
988 e_not->where = e_cond->where;
989 e_not->expr_type = EXPR_OP;
990 e_not->value.op.op = INTRINSIC_NOT;
991 e_not->value.op.op1 = e_cond;
993 /* Generate the EXIT statement. */
994 c_exit = XCNEW (gfc_code);
995 c_exit->op = EXEC_EXIT;
996 c_exit->ext.which_construct = co;
997 c_exit->loc = co->loc;
999 /* Generate the IF statement. */
1000 c_if2 = XCNEW (gfc_code);
1001 c_if2->op = EXEC_IF;
1002 c_if2->expr1 = e_not;
1003 c_if2->next = c_exit;
1004 c_if2->loc = co->loc;
1006 /* ... plus the one to chain it to. */
1007 c_if1 = XCNEW (gfc_code);
1008 c_if1->op = EXEC_IF;
1009 c_if1->block = c_if2;
1010 c_if1->loc = co->loc;
1012 /* Make the DO WHILE loop into a DO block by replacing the condition
1013 with a true constant. */
1014 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
1016 /* Hang the generated if statement into the loop body. */
1018 loopblock = co->block->next;
1019 co->block->next = c_if1;
1020 c_if1->next = loopblock;
1022 return 0;
1025 /* Code callback function for converting
1026 if (a) then
1028 else if (b) then
1029 end if
1031 into
1032 if (a) then
1033 else
1034 if (b) then
1035 end if
1036 end if
1038 because otherwise common function elimination would place the BLOCKs
1039 into the wrong place. */
1041 static int
1042 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1043 void *data ATTRIBUTE_UNUSED)
1045 gfc_code *co = *c;
1046 gfc_code *c_if1, *c_if2, *else_stmt;
1048 if (co->op != EXEC_IF)
1049 return 0;
1051 /* This loop starts out with the first ELSE statement. */
1052 else_stmt = co->block->block;
1054 while (else_stmt != NULL)
1056 gfc_code *next_else;
1058 /* If there is no condition, we're done. */
1059 if (else_stmt->expr1 == NULL)
1060 break;
1062 next_else = else_stmt->block;
1064 /* Generate the new IF statement. */
1065 c_if2 = XCNEW (gfc_code);
1066 c_if2->op = EXEC_IF;
1067 c_if2->expr1 = else_stmt->expr1;
1068 c_if2->next = else_stmt->next;
1069 c_if2->loc = else_stmt->loc;
1070 c_if2->block = next_else;
1072 /* ... plus the one to chain it to. */
1073 c_if1 = XCNEW (gfc_code);
1074 c_if1->op = EXEC_IF;
1075 c_if1->block = c_if2;
1076 c_if1->loc = else_stmt->loc;
1078 /* Insert the new IF after the ELSE. */
1079 else_stmt->expr1 = NULL;
1080 else_stmt->next = c_if1;
1081 else_stmt->block = NULL;
1083 else_stmt = next_else;
1085 /* Don't walk subtrees. */
1086 return 0;
1089 struct do_stack
1091 struct do_stack *prev;
1092 gfc_iterator *iter;
1093 gfc_code *code;
1094 } *stack_top;
1096 /* Recursively traverse the block of a WRITE or READ statement, and maybe
1097 optimize by replacing do loops with their analog array slices. For
1098 example:
1100 write (*,*) (a(i), i=1,4)
1102 is replaced with
1104 write (*,*) a(1:4:1) . */
1106 static bool
1107 traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
1109 gfc_code *curr;
1110 gfc_expr *new_e, *expr, *start;
1111 gfc_ref *ref;
1112 struct do_stack ds_push;
1113 int i, future_rank = 0;
1114 gfc_iterator *iters[GFC_MAX_DIMENSIONS];
1115 gfc_expr *e;
1117 /* Find the first transfer/do statement. */
1118 for (curr = code; curr; curr = curr->next)
1120 if (curr->op == EXEC_DO || curr->op == EXEC_TRANSFER)
1121 break;
1124 /* Ensure it is the only transfer/do statement because cases like
1126 write (*,*) (a(i), b(i), i=1,4)
1128 cannot be optimized. */
1130 if (!curr || curr->next)
1131 return false;
1133 if (curr->op == EXEC_DO)
1135 if (curr->ext.iterator->var->ref)
1136 return false;
1137 ds_push.prev = stack_top;
1138 ds_push.iter = curr->ext.iterator;
1139 ds_push.code = curr;
1140 stack_top = &ds_push;
1141 if (traverse_io_block (curr->block->next, has_reached, prev))
1143 if (curr != stack_top->code && !*has_reached)
1145 curr->block->next = NULL;
1146 gfc_free_statements (curr);
1148 else
1149 *has_reached = true;
1150 return true;
1152 return false;
1155 gcc_assert (curr->op == EXEC_TRANSFER);
1157 /* FIXME: Workaround for PR 80945 - array slices with deferred character
1158 lenghts do not work. Remove this section when the PR is fixed. */
1159 e = curr->expr1;
1160 if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
1161 && e->ts.deferred)
1162 return false;
1163 /* End of section to be removed. */
1165 ref = e->ref;
1166 if (!ref || ref->type != REF_ARRAY || ref->u.ar.codimen != 0 || ref->next)
1167 return false;
1169 /* Find the iterators belonging to each variable and check conditions. */
1170 for (i = 0; i < ref->u.ar.dimen; i++)
1172 if (!ref->u.ar.start[i] || ref->u.ar.start[i]->ref
1173 || ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1174 return false;
1176 start = ref->u.ar.start[i];
1177 gfc_simplify_expr (start, 0);
1178 switch (start->expr_type)
1180 case EXPR_VARIABLE:
1182 /* write (*,*) (a(i), i=a%b,1) not handled yet. */
1183 if (start->ref)
1184 return false;
1186 /* Check for (a(k), i=1,4) or ((a(j, i), i=1,4), j=1,4). */
1187 if (!stack_top || !stack_top->iter
1188 || stack_top->iter->var->symtree != start->symtree)
1190 /* Check for (a(i,i), i=1,3). */
1191 int j;
1193 for (j=0; j<i; j++)
1194 if (iters[j] && iters[j]->var->symtree == start->symtree)
1195 return false;
1197 iters[i] = NULL;
1199 else
1201 iters[i] = stack_top->iter;
1202 stack_top = stack_top->prev;
1203 future_rank++;
1205 break;
1206 case EXPR_CONSTANT:
1207 iters[i] = NULL;
1208 break;
1209 case EXPR_OP:
1210 switch (start->value.op.op)
1212 case INTRINSIC_PLUS:
1213 case INTRINSIC_TIMES:
1214 if (start->value.op.op1->expr_type != EXPR_VARIABLE)
1215 std::swap (start->value.op.op1, start->value.op.op2);
1216 gcc_fallthrough ();
1217 case INTRINSIC_MINUS:
1218 if ((start->value.op.op1->expr_type!= EXPR_VARIABLE
1219 && start->value.op.op2->expr_type != EXPR_CONSTANT)
1220 || start->value.op.op1->ref)
1221 return false;
1222 if (!stack_top || !stack_top->iter
1223 || stack_top->iter->var->symtree
1224 != start->value.op.op1->symtree)
1225 return false;
1226 iters[i] = stack_top->iter;
1227 stack_top = stack_top->prev;
1228 break;
1229 default:
1230 return false;
1232 future_rank++;
1233 break;
1234 default:
1235 return false;
1239 /* Create new expr. */
1240 new_e = gfc_copy_expr (curr->expr1);
1241 new_e->expr_type = EXPR_VARIABLE;
1242 new_e->rank = future_rank;
1243 if (curr->expr1->shape)
1244 new_e->shape = gfc_get_shape (new_e->rank);
1246 /* Assign new starts, ends and strides if necessary. */
1247 for (i = 0; i < ref->u.ar.dimen; i++)
1249 if (!iters[i])
1250 continue;
1251 start = ref->u.ar.start[i];
1252 switch (start->expr_type)
1254 case EXPR_CONSTANT:
1255 gfc_internal_error ("bad expression");
1256 break;
1257 case EXPR_VARIABLE:
1258 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1259 new_e->ref->u.ar.type = AR_SECTION;
1260 gfc_free_expr (new_e->ref->u.ar.start[i]);
1261 new_e->ref->u.ar.start[i] = gfc_copy_expr (iters[i]->start);
1262 new_e->ref->u.ar.end[i] = gfc_copy_expr (iters[i]->end);
1263 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1264 break;
1265 case EXPR_OP:
1266 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1267 new_e->ref->u.ar.type = AR_SECTION;
1268 gfc_free_expr (new_e->ref->u.ar.start[i]);
1269 expr = gfc_copy_expr (start);
1270 expr->value.op.op1 = gfc_copy_expr (iters[i]->start);
1271 new_e->ref->u.ar.start[i] = expr;
1272 gfc_simplify_expr (new_e->ref->u.ar.start[i], 0);
1273 expr = gfc_copy_expr (start);
1274 expr->value.op.op1 = gfc_copy_expr (iters[i]->end);
1275 new_e->ref->u.ar.end[i] = expr;
1276 gfc_simplify_expr (new_e->ref->u.ar.end[i], 0);
1277 switch (start->value.op.op)
1279 case INTRINSIC_MINUS:
1280 case INTRINSIC_PLUS:
1281 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1282 break;
1283 case INTRINSIC_TIMES:
1284 expr = gfc_copy_expr (start);
1285 expr->value.op.op1 = gfc_copy_expr (iters[i]->step);
1286 new_e->ref->u.ar.stride[i] = expr;
1287 gfc_simplify_expr (new_e->ref->u.ar.stride[i], 0);
1288 break;
1289 default:
1290 gfc_internal_error ("bad op");
1292 break;
1293 default:
1294 gfc_internal_error ("bad expression");
1297 curr->expr1 = new_e;
1299 /* Insert modified statement. Check whether the statement needs to be
1300 inserted at the lowest level. */
1301 if (!stack_top->iter)
1303 if (prev)
1305 curr->next = prev->next->next;
1306 prev->next = curr;
1308 else
1310 curr->next = stack_top->code->block->next->next->next;
1311 stack_top->code->block->next = curr;
1314 else
1315 stack_top->code->block->next = curr;
1316 return true;
1319 /* Function for the gfc_code_walker. If code is a READ or WRITE statement, it
1320 tries to optimize its block. */
1322 static int
1323 simplify_io_impl_do (gfc_code **code, int *walk_subtrees,
1324 void *data ATTRIBUTE_UNUSED)
1326 gfc_code **curr, *prev = NULL;
1327 struct do_stack write, first;
1328 bool b = false;
1329 *walk_subtrees = 1;
1330 if (!(*code)->block
1331 || ((*code)->block->op != EXEC_WRITE
1332 && (*code)->block->op != EXEC_READ))
1333 return 0;
1335 *walk_subtrees = 0;
1336 write.prev = NULL;
1337 write.iter = NULL;
1338 write.code = *code;
1340 for (curr = &(*code)->block; *curr; curr = &(*curr)->next)
1342 if ((*curr)->op == EXEC_DO)
1344 first.prev = &write;
1345 first.iter = (*curr)->ext.iterator;
1346 first.code = *curr;
1347 stack_top = &first;
1348 traverse_io_block ((*curr)->block->next, &b, prev);
1349 stack_top = NULL;
1351 prev = *curr;
1353 return 0;
1356 /* Optimize a namespace, including all contained namespaces.
1357 flag_frontend_optimize and flag_fronend_loop_interchange are
1358 handled separately. */
1360 static void
1361 optimize_namespace (gfc_namespace *ns)
1363 gfc_namespace *saved_ns = gfc_current_ns;
1364 current_ns = ns;
1365 gfc_current_ns = ns;
1366 forall_level = 0;
1367 iterator_level = 0;
1368 in_assoc_list = false;
1369 in_omp_workshare = false;
1371 if (flag_frontend_optimize)
1373 gfc_code_walker (&ns->code, simplify_io_impl_do, dummy_expr_callback, NULL);
1374 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
1375 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
1376 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
1377 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
1378 if (flag_inline_matmul_limit != 0)
1380 bool found;
1383 found = false;
1384 gfc_code_walker (&ns->code, matmul_to_var_code, matmul_to_var_expr,
1385 (void *) &found);
1387 while (found);
1389 gfc_code_walker (&ns->code, matmul_temp_args, dummy_expr_callback,
1390 NULL);
1391 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
1392 NULL);
1396 if (flag_frontend_loop_interchange)
1397 gfc_code_walker (&ns->code, index_interchange, dummy_expr_callback,
1398 NULL);
1400 /* BLOCKs are handled in the expression walker below. */
1401 for (ns = ns->contained; ns; ns = ns->sibling)
1403 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1404 optimize_namespace (ns);
1406 gfc_current_ns = saved_ns;
1409 /* Handle dependencies for allocatable strings which potentially redefine
1410 themselves in an assignment. */
1412 static void
1413 realloc_strings (gfc_namespace *ns)
1415 current_ns = ns;
1416 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1418 for (ns = ns->contained; ns; ns = ns->sibling)
1420 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1421 realloc_strings (ns);
1426 static void
1427 optimize_reduction (gfc_namespace *ns)
1429 current_ns = ns;
1430 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1431 callback_reduction, NULL);
1433 /* BLOCKs are handled in the expression walker below. */
1434 for (ns = ns->contained; ns; ns = ns->sibling)
1436 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1437 optimize_reduction (ns);
1441 /* Replace code like
1442 a = matmul(b,c) + d
1443 with
1444 a = matmul(b,c) ; a = a + d
1445 where the array function is not elemental and not allocatable
1446 and does not depend on the left-hand side.
1449 static bool
1450 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1452 gfc_expr *e;
1454 if (!*rhs)
1455 return false;
1457 e = *rhs;
1458 if (e->expr_type == EXPR_OP)
1460 switch (e->value.op.op)
1462 /* Unary operators and exponentiation: Only look at a single
1463 operand. */
1464 case INTRINSIC_NOT:
1465 case INTRINSIC_UPLUS:
1466 case INTRINSIC_UMINUS:
1467 case INTRINSIC_PARENTHESES:
1468 case INTRINSIC_POWER:
1469 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
1470 return true;
1471 break;
1473 case INTRINSIC_CONCAT:
1474 /* Do not do string concatenations. */
1475 break;
1477 default:
1478 /* Binary operators. */
1479 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1480 return true;
1482 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1483 return true;
1485 break;
1488 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
1489 && ! (e->value.function.esym
1490 && (e->value.function.esym->attr.elemental
1491 || e->value.function.esym->attr.allocatable
1492 || e->value.function.esym->ts.type != c->expr1->ts.type
1493 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
1494 && ! (e->value.function.isym
1495 && (e->value.function.isym->elemental
1496 || e->ts.type != c->expr1->ts.type
1497 || e->ts.kind != c->expr1->ts.kind))
1498 && ! gfc_inline_intrinsic_function_p (e))
1501 gfc_code *n;
1502 gfc_expr *new_expr;
1504 /* Insert a new assignment statement after the current one. */
1505 n = XCNEW (gfc_code);
1506 n->op = EXEC_ASSIGN;
1507 n->loc = c->loc;
1508 n->next = c->next;
1509 c->next = n;
1511 n->expr1 = gfc_copy_expr (c->expr1);
1512 n->expr2 = c->expr2;
1513 new_expr = gfc_copy_expr (c->expr1);
1514 c->expr2 = e;
1515 *rhs = new_expr;
1517 return true;
1521 /* Nothing to optimize. */
1522 return false;
1525 /* Remove unneeded TRIMs at the end of expressions. */
1527 static bool
1528 remove_trim (gfc_expr *rhs)
1530 bool ret;
1532 ret = false;
1533 if (!rhs)
1534 return ret;
1536 /* Check for a // b // trim(c). Looping is probably not
1537 necessary because the parser usually generates
1538 (// (// a b ) trim(c) ) , but better safe than sorry. */
1540 while (rhs->expr_type == EXPR_OP
1541 && rhs->value.op.op == INTRINSIC_CONCAT)
1542 rhs = rhs->value.op.op2;
1544 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1545 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1547 strip_function_call (rhs);
1548 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1549 remove_trim (rhs);
1550 ret = true;
1553 return ret;
1556 /* Optimizations for an assignment. */
1558 static void
1559 optimize_assignment (gfc_code * c)
1561 gfc_expr *lhs, *rhs;
1563 lhs = c->expr1;
1564 rhs = c->expr2;
1566 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1568 /* Optimize a = trim(b) to a = b. */
1569 remove_trim (rhs);
1571 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1572 if (is_empty_string (rhs))
1573 rhs->value.character.length = 0;
1576 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1577 optimize_binop_array_assignment (c, &rhs, false);
1581 /* Remove an unneeded function call, modifying the expression.
1582 This replaces the function call with the value of its
1583 first argument. The rest of the argument list is freed. */
1585 static void
1586 strip_function_call (gfc_expr *e)
1588 gfc_expr *e1;
1589 gfc_actual_arglist *a;
1591 a = e->value.function.actual;
1593 /* We should have at least one argument. */
1594 gcc_assert (a->expr != NULL);
1596 e1 = a->expr;
1598 /* Free the remaining arglist, if any. */
1599 if (a->next)
1600 gfc_free_actual_arglist (a->next);
1602 /* Graft the argument expression onto the original function. */
1603 *e = *e1;
1604 free (e1);
1608 /* Optimization of lexical comparison functions. */
1610 static bool
1611 optimize_lexical_comparison (gfc_expr *e)
1613 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1614 return false;
1616 switch (e->value.function.isym->id)
1618 case GFC_ISYM_LLE:
1619 return optimize_comparison (e, INTRINSIC_LE);
1621 case GFC_ISYM_LGE:
1622 return optimize_comparison (e, INTRINSIC_GE);
1624 case GFC_ISYM_LGT:
1625 return optimize_comparison (e, INTRINSIC_GT);
1627 case GFC_ISYM_LLT:
1628 return optimize_comparison (e, INTRINSIC_LT);
1630 default:
1631 break;
1633 return false;
1636 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1637 do CHARACTER because of possible pessimization involving character
1638 lengths. */
1640 static bool
1641 combine_array_constructor (gfc_expr *e)
1644 gfc_expr *op1, *op2;
1645 gfc_expr *scalar;
1646 gfc_expr *new_expr;
1647 gfc_constructor *c, *new_c;
1648 gfc_constructor_base oldbase, newbase;
1649 bool scalar_first;
1650 int n_elem;
1651 bool all_const;
1653 /* Array constructors have rank one. */
1654 if (e->rank != 1)
1655 return false;
1657 /* Don't try to combine association lists, this makes no sense
1658 and leads to an ICE. */
1659 if (in_assoc_list)
1660 return false;
1662 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1663 if (forall_level > 0)
1664 return false;
1666 /* Inside an iterator, things can get hairy; we are likely to create
1667 an invalid temporary variable. */
1668 if (iterator_level > 0)
1669 return false;
1671 op1 = e->value.op.op1;
1672 op2 = e->value.op.op2;
1674 if (!op1 || !op2)
1675 return false;
1677 if (op1->expr_type == EXPR_ARRAY && op2->rank == 0)
1678 scalar_first = false;
1679 else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0)
1681 scalar_first = true;
1682 op1 = e->value.op.op2;
1683 op2 = e->value.op.op1;
1685 else
1686 return false;
1688 if (op2->ts.type == BT_CHARACTER)
1689 return false;
1691 /* This might be an expanded constructor with very many constant values. If
1692 we perform the operation here, we might end up with a long compile time
1693 and actually longer execution time, so a length bound is in order here.
1694 If the constructor constains something which is not a constant, it did
1695 not come from an expansion, so leave it alone. */
1697 #define CONSTR_LEN_MAX 4
1699 oldbase = op1->value.constructor;
1701 n_elem = 0;
1702 all_const = true;
1703 for (c = gfc_constructor_first (oldbase); c; c = gfc_constructor_next(c))
1705 if (c->expr->expr_type != EXPR_CONSTANT)
1707 all_const = false;
1708 break;
1710 n_elem += 1;
1713 if (all_const && n_elem > CONSTR_LEN_MAX)
1714 return false;
1716 #undef CONSTR_LEN_MAX
1718 newbase = NULL;
1719 e->expr_type = EXPR_ARRAY;
1721 scalar = create_var (gfc_copy_expr (op2), "constr");
1723 for (c = gfc_constructor_first (oldbase); c;
1724 c = gfc_constructor_next (c))
1726 new_expr = gfc_get_expr ();
1727 new_expr->ts = e->ts;
1728 new_expr->expr_type = EXPR_OP;
1729 new_expr->rank = c->expr->rank;
1730 new_expr->where = c->expr->where;
1731 new_expr->value.op.op = e->value.op.op;
1733 if (scalar_first)
1735 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1736 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1738 else
1740 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1741 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1744 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1745 new_c->iterator = c->iterator;
1746 c->iterator = NULL;
1749 gfc_free_expr (op1);
1750 gfc_free_expr (op2);
1751 gfc_free_expr (scalar);
1753 e->value.constructor = newbase;
1754 return true;
1757 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1758 2**k into ishift(1,k) */
1760 static bool
1761 optimize_power (gfc_expr *e)
1763 gfc_expr *op1, *op2;
1764 gfc_expr *iand, *ishft;
1766 if (e->ts.type != BT_INTEGER)
1767 return false;
1769 op1 = e->value.op.op1;
1771 if (op1 == NULL || op1->expr_type != EXPR_CONSTANT)
1772 return false;
1774 if (mpz_cmp_si (op1->value.integer, -1L) == 0)
1776 gfc_free_expr (op1);
1778 op2 = e->value.op.op2;
1780 if (op2 == NULL)
1781 return false;
1783 iand = gfc_build_intrinsic_call (current_ns, GFC_ISYM_IAND,
1784 "_internal_iand", e->where, 2, op2,
1785 gfc_get_int_expr (e->ts.kind,
1786 &e->where, 1));
1788 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1789 "_internal_ishft", e->where, 2, iand,
1790 gfc_get_int_expr (e->ts.kind,
1791 &e->where, 1));
1793 e->value.op.op = INTRINSIC_MINUS;
1794 e->value.op.op1 = gfc_get_int_expr (e->ts.kind, &e->where, 1);
1795 e->value.op.op2 = ishft;
1796 return true;
1798 else if (mpz_cmp_si (op1->value.integer, 2L) == 0)
1800 gfc_free_expr (op1);
1802 op2 = e->value.op.op2;
1803 if (op2 == NULL)
1804 return false;
1806 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1807 "_internal_ishft", e->where, 2,
1808 gfc_get_int_expr (e->ts.kind,
1809 &e->where, 1),
1810 op2);
1811 *e = *ishft;
1812 return true;
1815 else if (mpz_cmp_si (op1->value.integer, 1L) == 0)
1817 op2 = e->value.op.op2;
1818 if (op2 == NULL)
1819 return false;
1821 gfc_free_expr (op1);
1822 gfc_free_expr (op2);
1824 e->expr_type = EXPR_CONSTANT;
1825 e->value.op.op1 = NULL;
1826 e->value.op.op2 = NULL;
1827 mpz_init_set_si (e->value.integer, 1);
1828 /* Typespec and location are still OK. */
1829 return true;
1832 return false;
1835 /* Recursive optimization of operators. */
1837 static bool
1838 optimize_op (gfc_expr *e)
1840 bool changed;
1842 gfc_intrinsic_op op = e->value.op.op;
1844 changed = false;
1846 /* Only use new-style comparisons. */
1847 switch(op)
1849 case INTRINSIC_EQ_OS:
1850 op = INTRINSIC_EQ;
1851 break;
1853 case INTRINSIC_GE_OS:
1854 op = INTRINSIC_GE;
1855 break;
1857 case INTRINSIC_LE_OS:
1858 op = INTRINSIC_LE;
1859 break;
1861 case INTRINSIC_NE_OS:
1862 op = INTRINSIC_NE;
1863 break;
1865 case INTRINSIC_GT_OS:
1866 op = INTRINSIC_GT;
1867 break;
1869 case INTRINSIC_LT_OS:
1870 op = INTRINSIC_LT;
1871 break;
1873 default:
1874 break;
1877 switch (op)
1879 case INTRINSIC_EQ:
1880 case INTRINSIC_GE:
1881 case INTRINSIC_LE:
1882 case INTRINSIC_NE:
1883 case INTRINSIC_GT:
1884 case INTRINSIC_LT:
1885 changed = optimize_comparison (e, op);
1887 gcc_fallthrough ();
1888 /* Look at array constructors. */
1889 case INTRINSIC_PLUS:
1890 case INTRINSIC_MINUS:
1891 case INTRINSIC_TIMES:
1892 case INTRINSIC_DIVIDE:
1893 return combine_array_constructor (e) || changed;
1895 case INTRINSIC_POWER:
1896 return optimize_power (e);
1898 default:
1899 break;
1902 return false;
1906 /* Return true if a constant string contains only blanks. */
1908 static bool
1909 is_empty_string (gfc_expr *e)
1911 int i;
1913 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1914 return false;
1916 for (i=0; i < e->value.character.length; i++)
1918 if (e->value.character.string[i] != ' ')
1919 return false;
1922 return true;
1926 /* Insert a call to the intrinsic len_trim. Use a different name for
1927 the symbol tree so we don't run into trouble when the user has
1928 renamed len_trim for some reason. */
1930 static gfc_expr*
1931 get_len_trim_call (gfc_expr *str, int kind)
1933 gfc_expr *fcn;
1934 gfc_actual_arglist *actual_arglist, *next;
1936 fcn = gfc_get_expr ();
1937 fcn->expr_type = EXPR_FUNCTION;
1938 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1939 actual_arglist = gfc_get_actual_arglist ();
1940 actual_arglist->expr = str;
1941 next = gfc_get_actual_arglist ();
1942 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, kind);
1943 actual_arglist->next = next;
1945 fcn->value.function.actual = actual_arglist;
1946 fcn->where = str->where;
1947 fcn->ts.type = BT_INTEGER;
1948 fcn->ts.kind = gfc_charlen_int_kind;
1950 gfc_get_sym_tree ("__internal_len_trim", current_ns, &fcn->symtree, false);
1951 fcn->symtree->n.sym->ts = fcn->ts;
1952 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1953 fcn->symtree->n.sym->attr.function = 1;
1954 fcn->symtree->n.sym->attr.elemental = 1;
1955 fcn->symtree->n.sym->attr.referenced = 1;
1956 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
1957 gfc_commit_symbol (fcn->symtree->n.sym);
1959 return fcn;
1962 /* Optimize expressions for equality. */
1964 static bool
1965 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1967 gfc_expr *op1, *op2;
1968 bool change;
1969 int eq;
1970 bool result;
1971 gfc_actual_arglist *firstarg, *secondarg;
1973 if (e->expr_type == EXPR_OP)
1975 firstarg = NULL;
1976 secondarg = NULL;
1977 op1 = e->value.op.op1;
1978 op2 = e->value.op.op2;
1980 else if (e->expr_type == EXPR_FUNCTION)
1982 /* One of the lexical comparison functions. */
1983 firstarg = e->value.function.actual;
1984 secondarg = firstarg->next;
1985 op1 = firstarg->expr;
1986 op2 = secondarg->expr;
1988 else
1989 gcc_unreachable ();
1991 /* Strip off unneeded TRIM calls from string comparisons. */
1993 change = remove_trim (op1);
1995 if (remove_trim (op2))
1996 change = true;
1998 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1999 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
2000 handles them well). However, there are also cases that need a non-scalar
2001 argument. For example the any intrinsic. See PR 45380. */
2002 if (e->rank > 0)
2003 return change;
2005 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
2006 len_trim(a) != 0 */
2007 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
2008 && (op == INTRINSIC_EQ || op == INTRINSIC_NE))
2010 bool empty_op1, empty_op2;
2011 empty_op1 = is_empty_string (op1);
2012 empty_op2 = is_empty_string (op2);
2014 if (empty_op1 || empty_op2)
2016 gfc_expr *fcn;
2017 gfc_expr *zero;
2018 gfc_expr *str;
2020 /* This can only happen when an error for comparing
2021 characters of different kinds has already been issued. */
2022 if (empty_op1 && empty_op2)
2023 return false;
2025 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
2026 str = empty_op1 ? op2 : op1;
2028 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
2031 if (empty_op1)
2032 gfc_free_expr (op1);
2033 else
2034 gfc_free_expr (op2);
2036 op1 = fcn;
2037 op2 = zero;
2038 e->value.op.op1 = fcn;
2039 e->value.op.op2 = zero;
2044 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
2046 if (flag_finite_math_only
2047 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
2048 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
2050 eq = gfc_dep_compare_expr (op1, op2);
2051 if (eq <= -2)
2053 /* Replace A // B < A // C with B < C, and A // B < C // B
2054 with A < C. */
2055 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
2056 && op1->expr_type == EXPR_OP
2057 && op1->value.op.op == INTRINSIC_CONCAT
2058 && op2->expr_type == EXPR_OP
2059 && op2->value.op.op == INTRINSIC_CONCAT)
2061 gfc_expr *op1_left = op1->value.op.op1;
2062 gfc_expr *op2_left = op2->value.op.op1;
2063 gfc_expr *op1_right = op1->value.op.op2;
2064 gfc_expr *op2_right = op2->value.op.op2;
2066 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
2068 /* Watch out for 'A ' // x vs. 'A' // x. */
2070 if (op1_left->expr_type == EXPR_CONSTANT
2071 && op2_left->expr_type == EXPR_CONSTANT
2072 && op1_left->value.character.length
2073 != op2_left->value.character.length)
2074 return change;
2075 else
2077 free (op1_left);
2078 free (op2_left);
2079 if (firstarg)
2081 firstarg->expr = op1_right;
2082 secondarg->expr = op2_right;
2084 else
2086 e->value.op.op1 = op1_right;
2087 e->value.op.op2 = op2_right;
2089 optimize_comparison (e, op);
2090 return true;
2093 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
2095 free (op1_right);
2096 free (op2_right);
2097 if (firstarg)
2099 firstarg->expr = op1_left;
2100 secondarg->expr = op2_left;
2102 else
2104 e->value.op.op1 = op1_left;
2105 e->value.op.op2 = op2_left;
2108 optimize_comparison (e, op);
2109 return true;
2113 else
2115 /* eq can only be -1, 0 or 1 at this point. */
2116 switch (op)
2118 case INTRINSIC_EQ:
2119 result = eq == 0;
2120 break;
2122 case INTRINSIC_GE:
2123 result = eq >= 0;
2124 break;
2126 case INTRINSIC_LE:
2127 result = eq <= 0;
2128 break;
2130 case INTRINSIC_NE:
2131 result = eq != 0;
2132 break;
2134 case INTRINSIC_GT:
2135 result = eq > 0;
2136 break;
2138 case INTRINSIC_LT:
2139 result = eq < 0;
2140 break;
2142 default:
2143 gfc_internal_error ("illegal OP in optimize_comparison");
2144 break;
2147 /* Replace the expression by a constant expression. The typespec
2148 and where remains the way it is. */
2149 free (op1);
2150 free (op2);
2151 e->expr_type = EXPR_CONSTANT;
2152 e->value.logical = result;
2153 return true;
2157 return change;
2160 /* Optimize a trim function by replacing it with an equivalent substring
2161 involving a call to len_trim. This only works for expressions where
2162 variables are trimmed. Return true if anything was modified. */
2164 static bool
2165 optimize_trim (gfc_expr *e)
2167 gfc_expr *a;
2168 gfc_ref *ref;
2169 gfc_expr *fcn;
2170 gfc_ref **rr = NULL;
2172 /* Don't do this optimization within an argument list, because
2173 otherwise aliasing issues may occur. */
2175 if (count_arglist != 1)
2176 return false;
2178 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
2179 || e->value.function.isym == NULL
2180 || e->value.function.isym->id != GFC_ISYM_TRIM)
2181 return false;
2183 a = e->value.function.actual->expr;
2185 if (a->expr_type != EXPR_VARIABLE)
2186 return false;
2188 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
2190 if (a->symtree->n.sym->attr.allocatable)
2191 return false;
2193 /* Follow all references to find the correct place to put the newly
2194 created reference. FIXME: Also handle substring references and
2195 array references. Array references cause strange regressions at
2196 the moment. */
2198 if (a->ref)
2200 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
2202 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
2203 return false;
2207 strip_function_call (e);
2209 if (e->ref == NULL)
2210 rr = &(e->ref);
2212 /* Create the reference. */
2214 ref = gfc_get_ref ();
2215 ref->type = REF_SUBSTRING;
2217 /* Set the start of the reference. */
2219 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
2221 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
2223 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_default_integer_kind);
2225 /* Set the end of the reference to the call to len_trim. */
2227 ref->u.ss.end = fcn;
2228 gcc_assert (rr != NULL && *rr == NULL);
2229 *rr = ref;
2230 return true;
2233 /* Optimize minloc(b), where b is rank 1 array, into
2234 (/ minloc(b, dim=1) /), and similarly for maxloc,
2235 as the latter forms are expanded inline. */
2237 static void
2238 optimize_minmaxloc (gfc_expr **e)
2240 gfc_expr *fn = *e;
2241 gfc_actual_arglist *a;
2242 char *name, *p;
2244 if (fn->rank != 1
2245 || fn->value.function.actual == NULL
2246 || fn->value.function.actual->expr == NULL
2247 || fn->value.function.actual->expr->rank != 1)
2248 return;
2250 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
2251 (*e)->shape = fn->shape;
2252 fn->rank = 0;
2253 fn->shape = NULL;
2254 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
2256 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
2257 strcpy (name, fn->value.function.name);
2258 p = strstr (name, "loc0");
2259 p[3] = '1';
2260 fn->value.function.name = gfc_get_string ("%s", name);
2261 if (fn->value.function.actual->next)
2263 a = fn->value.function.actual->next;
2264 gcc_assert (a->expr == NULL);
2266 else
2268 a = gfc_get_actual_arglist ();
2269 fn->value.function.actual->next = a;
2271 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
2272 &fn->where);
2273 mpz_set_ui (a->expr->value.integer, 1);
2276 /* Callback function for code checking that we do not pass a DO variable to an
2277 INTENT(OUT) or INTENT(INOUT) dummy variable. */
2279 static int
2280 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2281 void *data ATTRIBUTE_UNUSED)
2283 gfc_code *co;
2284 int i;
2285 gfc_formal_arglist *f;
2286 gfc_actual_arglist *a;
2287 gfc_code *cl;
2288 do_t loop, *lp;
2289 bool seen_goto;
2291 co = *c;
2293 /* If the doloop_list grew, we have to truncate it here. */
2295 if ((unsigned) doloop_level < doloop_list.length())
2296 doloop_list.truncate (doloop_level);
2298 seen_goto = false;
2299 switch (co->op)
2301 case EXEC_DO:
2303 if (co->ext.iterator && co->ext.iterator->var)
2304 loop.c = co;
2305 else
2306 loop.c = NULL;
2308 loop.branch_level = if_level + select_level;
2309 loop.seen_goto = false;
2310 doloop_list.safe_push (loop);
2311 break;
2313 /* If anything could transfer control away from a suspicious
2314 subscript, make sure to set seen_goto in the current DO loop
2315 (if any). */
2316 case EXEC_GOTO:
2317 case EXEC_EXIT:
2318 case EXEC_STOP:
2319 case EXEC_ERROR_STOP:
2320 case EXEC_CYCLE:
2321 seen_goto = true;
2322 break;
2324 case EXEC_OPEN:
2325 if (co->ext.open->err)
2326 seen_goto = true;
2327 break;
2329 case EXEC_CLOSE:
2330 if (co->ext.close->err)
2331 seen_goto = true;
2332 break;
2334 case EXEC_BACKSPACE:
2335 case EXEC_ENDFILE:
2336 case EXEC_REWIND:
2337 case EXEC_FLUSH:
2339 if (co->ext.filepos->err)
2340 seen_goto = true;
2341 break;
2343 case EXEC_INQUIRE:
2344 if (co->ext.filepos->err)
2345 seen_goto = true;
2346 break;
2348 case EXEC_READ:
2349 case EXEC_WRITE:
2350 if (co->ext.dt->err || co->ext.dt->end || co->ext.dt->eor)
2351 seen_goto = true;
2352 break;
2354 case EXEC_WAIT:
2355 if (co->ext.wait->err || co->ext.wait->end || co->ext.wait->eor)
2356 loop.seen_goto = true;
2357 break;
2359 case EXEC_CALL:
2361 if (co->resolved_sym == NULL)
2362 break;
2364 f = gfc_sym_get_dummy_args (co->resolved_sym);
2366 /* Withot a formal arglist, there is only unknown INTENT,
2367 which we don't check for. */
2368 if (f == NULL)
2369 break;
2371 a = co->ext.actual;
2373 while (a && f)
2375 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2377 gfc_symbol *do_sym;
2378 cl = lp->c;
2380 if (cl == NULL)
2381 break;
2383 do_sym = cl->ext.iterator->var->symtree->n.sym;
2385 if (a->expr && a->expr->symtree
2386 && a->expr->symtree->n.sym == do_sym)
2388 if (f->sym->attr.intent == INTENT_OUT)
2389 gfc_error_now ("Variable %qs at %L set to undefined "
2390 "value inside loop beginning at %L as "
2391 "INTENT(OUT) argument to subroutine %qs",
2392 do_sym->name, &a->expr->where,
2393 &(doloop_list[i].c->loc),
2394 co->symtree->n.sym->name);
2395 else if (f->sym->attr.intent == INTENT_INOUT)
2396 gfc_error_now ("Variable %qs at %L not definable inside "
2397 "loop beginning at %L as INTENT(INOUT) "
2398 "argument to subroutine %qs",
2399 do_sym->name, &a->expr->where,
2400 &(doloop_list[i].c->loc),
2401 co->symtree->n.sym->name);
2404 a = a->next;
2405 f = f->next;
2407 break;
2409 default:
2410 break;
2412 if (seen_goto && doloop_level > 0)
2413 doloop_list[doloop_level-1].seen_goto = true;
2415 return 0;
2418 /* Callback function to warn about different things within DO loops. */
2420 static int
2421 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2422 void *data ATTRIBUTE_UNUSED)
2424 do_t *last;
2426 if (doloop_list.length () == 0)
2427 return 0;
2429 if ((*e)->expr_type == EXPR_FUNCTION)
2430 do_intent (e);
2432 last = &doloop_list.last();
2433 if (last->seen_goto && !warn_do_subscript)
2434 return 0;
2436 if ((*e)->expr_type == EXPR_VARIABLE)
2437 do_subscript (e);
2439 return 0;
2442 typedef struct
2444 gfc_symbol *sym;
2445 mpz_t val;
2446 } insert_index_t;
2448 /* Callback function - if the expression is the variable in data->sym,
2449 replace it with a constant from data->val. */
2451 static int
2452 callback_insert_index (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2453 void *data)
2455 insert_index_t *d;
2456 gfc_expr *ex, *n;
2458 ex = (*e);
2459 if (ex->expr_type != EXPR_VARIABLE)
2460 return 0;
2462 d = (insert_index_t *) data;
2463 if (ex->symtree->n.sym != d->sym)
2464 return 0;
2466 n = gfc_get_constant_expr (BT_INTEGER, ex->ts.kind, &ex->where);
2467 mpz_set (n->value.integer, d->val);
2469 gfc_free_expr (ex);
2470 *e = n;
2471 return 0;
2474 /* In the expression e, replace occurrences of the variable sym with
2475 val. If this results in a constant expression, return true and
2476 return the value in ret. Return false if the expression already
2477 is a constant. Caller has to clear ret in that case. */
2479 static bool
2480 insert_index (gfc_expr *e, gfc_symbol *sym, mpz_t val, mpz_t ret)
2482 gfc_expr *n;
2483 insert_index_t data;
2484 bool rc;
2486 if (e->expr_type == EXPR_CONSTANT)
2487 return false;
2489 n = gfc_copy_expr (e);
2490 data.sym = sym;
2491 mpz_init_set (data.val, val);
2492 gfc_expr_walker (&n, callback_insert_index, (void *) &data);
2493 gfc_simplify_expr (n, 0);
2495 if (n->expr_type == EXPR_CONSTANT)
2497 rc = true;
2498 mpz_init_set (ret, n->value.integer);
2500 else
2501 rc = false;
2503 mpz_clear (data.val);
2504 gfc_free_expr (n);
2505 return rc;
2509 /* Check array subscripts for possible out-of-bounds accesses in DO
2510 loops with constant bounds. */
2512 static int
2513 do_subscript (gfc_expr **e)
2515 gfc_expr *v;
2516 gfc_array_ref *ar;
2517 gfc_ref *ref;
2518 int i,j;
2519 gfc_code *dl;
2520 do_t *lp;
2522 v = *e;
2523 /* Constants are already checked. */
2524 if (v->expr_type == EXPR_CONSTANT)
2525 return 0;
2527 /* Wrong warnings will be generated in an associate list. */
2528 if (in_assoc_list)
2529 return 0;
2531 for (ref = v->ref; ref; ref = ref->next)
2533 if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT)
2535 ar = & ref->u.ar;
2536 FOR_EACH_VEC_ELT (doloop_list, j, lp)
2538 gfc_symbol *do_sym;
2539 mpz_t do_start, do_step, do_end;
2540 bool have_do_start, have_do_end;
2541 bool error_not_proven;
2542 int warn;
2544 dl = lp->c;
2545 if (dl == NULL)
2546 break;
2548 /* If we are within a branch, or a goto or equivalent
2549 was seen in the DO loop before, then we cannot prove that
2550 this expression is actually evaluated. Don't do anything
2551 unless we want to see it all. */
2552 error_not_proven = lp->seen_goto
2553 || lp->branch_level < if_level + select_level;
2555 if (error_not_proven && !warn_do_subscript)
2556 break;
2558 if (error_not_proven)
2559 warn = OPT_Wdo_subscript;
2560 else
2561 warn = 0;
2563 do_sym = dl->ext.iterator->var->symtree->n.sym;
2564 if (do_sym->ts.type != BT_INTEGER)
2565 continue;
2567 /* If we do not know about the stepsize, the loop may be zero trip.
2568 Do not warn in this case. */
2570 if (dl->ext.iterator->step->expr_type == EXPR_CONSTANT)
2571 mpz_init_set (do_step, dl->ext.iterator->step->value.integer);
2572 else
2573 continue;
2575 if (dl->ext.iterator->start->expr_type == EXPR_CONSTANT)
2577 have_do_start = true;
2578 mpz_init_set (do_start, dl->ext.iterator->start->value.integer);
2580 else
2581 have_do_start = false;
2584 if (dl->ext.iterator->end->expr_type == EXPR_CONSTANT)
2586 have_do_end = true;
2587 mpz_init_set (do_end, dl->ext.iterator->end->value.integer);
2589 else
2590 have_do_end = false;
2592 if (!have_do_start && !have_do_end)
2593 return 0;
2595 /* May have to correct the end value if the step does not equal
2596 one. */
2597 if (have_do_start && have_do_end && mpz_cmp_ui (do_step, 1) != 0)
2599 mpz_t diff, rem;
2601 mpz_init (diff);
2602 mpz_init (rem);
2603 mpz_sub (diff, do_end, do_start);
2604 mpz_tdiv_r (rem, diff, do_step);
2605 mpz_sub (do_end, do_end, rem);
2606 mpz_clear (diff);
2607 mpz_clear (rem);
2610 for (i = 0; i< ar->dimen; i++)
2612 mpz_t val;
2613 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_start
2614 && insert_index (ar->start[i], do_sym, do_start, val))
2616 if (ar->as->lower[i]
2617 && ar->as->lower[i]->expr_type == EXPR_CONSTANT
2618 && mpz_cmp (val, ar->as->lower[i]->value.integer) < 0)
2619 gfc_warning (warn, "Array reference at %L out of bounds "
2620 "(%ld < %ld) in loop beginning at %L",
2621 &ar->start[i]->where, mpz_get_si (val),
2622 mpz_get_si (ar->as->lower[i]->value.integer),
2623 &doloop_list[j].c->loc);
2625 if (ar->as->upper[i]
2626 && ar->as->upper[i]->expr_type == EXPR_CONSTANT
2627 && mpz_cmp (val, ar->as->upper[i]->value.integer) > 0)
2628 gfc_warning (warn, "Array reference at %L out of bounds "
2629 "(%ld > %ld) in loop beginning at %L",
2630 &ar->start[i]->where, mpz_get_si (val),
2631 mpz_get_si (ar->as->upper[i]->value.integer),
2632 &doloop_list[j].c->loc);
2634 mpz_clear (val);
2637 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_end
2638 && insert_index (ar->start[i], do_sym, do_end, val))
2640 if (ar->as->lower[i]
2641 && ar->as->lower[i]->expr_type == EXPR_CONSTANT
2642 && mpz_cmp (val, ar->as->lower[i]->value.integer) < 0)
2643 gfc_warning (warn, "Array reference at %L out of bounds "
2644 "(%ld < %ld) in loop beginning at %L",
2645 &ar->start[i]->where, mpz_get_si (val),
2646 mpz_get_si (ar->as->lower[i]->value.integer),
2647 &doloop_list[j].c->loc);
2649 if (ar->as->upper[i]
2650 && ar->as->upper[i]->expr_type == EXPR_CONSTANT
2651 && mpz_cmp (val, ar->as->upper[i]->value.integer) > 0)
2652 gfc_warning (warn, "Array reference at %L out of bounds "
2653 "(%ld > %ld) in loop beginning at %L",
2654 &ar->start[i]->where, mpz_get_si (val),
2655 mpz_get_si (ar->as->upper[i]->value.integer),
2656 &doloop_list[j].c->loc);
2658 mpz_clear (val);
2664 return 0;
2666 /* Function for functions checking that we do not pass a DO variable
2667 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
2669 static int
2670 do_intent (gfc_expr **e)
2672 gfc_formal_arglist *f;
2673 gfc_actual_arglist *a;
2674 gfc_expr *expr;
2675 gfc_code *dl;
2676 do_t *lp;
2677 int i;
2679 expr = *e;
2680 if (expr->expr_type != EXPR_FUNCTION)
2681 return 0;
2683 /* Intrinsic functions don't modify their arguments. */
2685 if (expr->value.function.isym)
2686 return 0;
2688 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
2690 /* Without a formal arglist, there is only unknown INTENT,
2691 which we don't check for. */
2692 if (f == NULL)
2693 return 0;
2695 a = expr->value.function.actual;
2697 while (a && f)
2699 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2701 gfc_symbol *do_sym;
2702 dl = lp->c;
2703 if (dl == NULL)
2704 break;
2706 do_sym = dl->ext.iterator->var->symtree->n.sym;
2708 if (a->expr && a->expr->symtree
2709 && a->expr->symtree->n.sym == do_sym)
2711 if (f->sym->attr.intent == INTENT_OUT)
2712 gfc_error_now ("Variable %qs at %L set to undefined value "
2713 "inside loop beginning at %L as INTENT(OUT) "
2714 "argument to function %qs", do_sym->name,
2715 &a->expr->where, &doloop_list[i].c->loc,
2716 expr->symtree->n.sym->name);
2717 else if (f->sym->attr.intent == INTENT_INOUT)
2718 gfc_error_now ("Variable %qs at %L not definable inside loop"
2719 " beginning at %L as INTENT(INOUT) argument to"
2720 " function %qs", do_sym->name,
2721 &a->expr->where, &doloop_list[i].c->loc,
2722 expr->symtree->n.sym->name);
2725 a = a->next;
2726 f = f->next;
2729 return 0;
2732 static void
2733 doloop_warn (gfc_namespace *ns)
2735 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
2738 /* This selction deals with inlining calls to MATMUL. */
2740 /* Replace calls to matmul outside of straight assignments with a temporary
2741 variable so that later inlining will work. */
2743 static int
2744 matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
2745 void *data)
2747 gfc_expr *e, *n;
2748 bool *found = (bool *) data;
2750 e = *ep;
2752 if (e->expr_type != EXPR_FUNCTION
2753 || e->value.function.isym == NULL
2754 || e->value.function.isym->id != GFC_ISYM_MATMUL)
2755 return 0;
2757 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2758 || in_where)
2759 return 0;
2761 /* Check if this is already in the form c = matmul(a,b). */
2763 if ((*current_code)->expr2 == e)
2764 return 0;
2766 n = create_var (e, "matmul");
2768 /* If create_var is unable to create a variable (for example if
2769 -fno-realloc-lhs is in force with a variable that does not have bounds
2770 known at compile-time), just return. */
2772 if (n == NULL)
2773 return 0;
2775 *ep = n;
2776 *found = true;
2777 return 0;
2780 /* Set current_code and associated variables so that matmul_to_var_expr can
2781 work. */
2783 static int
2784 matmul_to_var_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2785 void *data ATTRIBUTE_UNUSED)
2787 if (current_code != c)
2789 current_code = c;
2790 inserted_block = NULL;
2791 changed_statement = NULL;
2794 return 0;
2798 /* Take a statement of the shape c = matmul(a,b) and create temporaries
2799 for a and b if there is a dependency between the arguments and the
2800 result variable or if a or b are the result of calculations that cannot
2801 be handled by the inliner. */
2803 static int
2804 matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2805 void *data ATTRIBUTE_UNUSED)
2807 gfc_expr *expr1, *expr2;
2808 gfc_code *co;
2809 gfc_actual_arglist *a, *b;
2810 bool a_tmp, b_tmp;
2811 gfc_expr *matrix_a, *matrix_b;
2812 bool conjg_a, conjg_b, transpose_a, transpose_b;
2814 co = *c;
2816 if (co->op != EXEC_ASSIGN)
2817 return 0;
2819 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2820 || in_where)
2821 return 0;
2823 /* This has some duplication with inline_matmul_assign. This
2824 is because the creation of temporary variables could still fail,
2825 and inline_matmul_assign still needs to be able to handle these
2826 cases. */
2827 expr1 = co->expr1;
2828 expr2 = co->expr2;
2830 if (expr2->expr_type != EXPR_FUNCTION
2831 || expr2->value.function.isym == NULL
2832 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
2833 return 0;
2835 a_tmp = false;
2836 a = expr2->value.function.actual;
2837 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
2838 if (matrix_a != NULL)
2840 if (matrix_a->expr_type == EXPR_VARIABLE
2841 && (gfc_check_dependency (matrix_a, expr1, true)
2842 || has_dimen_vector_ref (matrix_a)))
2843 a_tmp = true;
2845 else
2846 a_tmp = true;
2848 b_tmp = false;
2849 b = a->next;
2850 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
2851 if (matrix_b != NULL)
2853 if (matrix_b->expr_type == EXPR_VARIABLE
2854 && (gfc_check_dependency (matrix_b, expr1, true)
2855 || has_dimen_vector_ref (matrix_b)))
2856 b_tmp = true;
2858 else
2859 b_tmp = true;
2861 if (!a_tmp && !b_tmp)
2862 return 0;
2864 current_code = c;
2865 inserted_block = NULL;
2866 changed_statement = NULL;
2867 if (a_tmp)
2869 gfc_expr *at;
2870 at = create_var (a->expr,"mma");
2871 if (at)
2872 a->expr = at;
2874 if (b_tmp)
2876 gfc_expr *bt;
2877 bt = create_var (b->expr,"mmb");
2878 if (bt)
2879 b->expr = bt;
2881 return 0;
2884 /* Auxiliary function to build and simplify an array inquiry function.
2885 dim is zero-based. */
2887 static gfc_expr *
2888 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim)
2890 gfc_expr *fcn;
2891 gfc_expr *dim_arg, *kind;
2892 const char *name;
2893 gfc_expr *ec;
2895 switch (id)
2897 case GFC_ISYM_LBOUND:
2898 name = "_gfortran_lbound";
2899 break;
2901 case GFC_ISYM_UBOUND:
2902 name = "_gfortran_ubound";
2903 break;
2905 case GFC_ISYM_SIZE:
2906 name = "_gfortran_size";
2907 break;
2909 default:
2910 gcc_unreachable ();
2913 dim_arg = gfc_get_int_expr (gfc_default_integer_kind, &e->where, dim);
2914 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2915 gfc_index_integer_kind);
2917 ec = gfc_copy_expr (e);
2918 fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3,
2919 ec, dim_arg, kind);
2920 gfc_simplify_expr (fcn, 0);
2921 return fcn;
2924 /* Builds a logical expression. */
2926 static gfc_expr*
2927 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2929 gfc_typespec ts;
2930 gfc_expr *res;
2932 ts.type = BT_LOGICAL;
2933 ts.kind = gfc_default_logical_kind;
2934 res = gfc_get_expr ();
2935 res->where = e1->where;
2936 res->expr_type = EXPR_OP;
2937 res->value.op.op = op;
2938 res->value.op.op1 = e1;
2939 res->value.op.op2 = e2;
2940 res->ts = ts;
2942 return res;
2946 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
2947 compatible typespecs. */
2949 static gfc_expr *
2950 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2952 gfc_expr *res;
2954 res = gfc_get_expr ();
2955 res->ts = e1->ts;
2956 res->where = e1->where;
2957 res->expr_type = EXPR_OP;
2958 res->value.op.op = op;
2959 res->value.op.op1 = e1;
2960 res->value.op.op2 = e2;
2961 gfc_simplify_expr (res, 0);
2962 return res;
2965 /* Generate the IF statement for a runtime check if we want to do inlining or
2966 not - putting in the code for both branches and putting it into the syntax
2967 tree is the caller's responsibility. For fixed array sizes, this should be
2968 removed by DCE. Only called for rank-two matrices A and B. */
2970 static gfc_code *
2971 inline_limit_check (gfc_expr *a, gfc_expr *b, enum matrix_case m_case)
2973 gfc_expr *inline_limit;
2974 gfc_code *if_1, *if_2, *else_2;
2975 gfc_expr *b2, *a2, *a1, *m1, *m2;
2976 gfc_typespec ts;
2977 gfc_expr *cond;
2979 gcc_assert (m_case == A2B2 || m_case == A2B2T || m_case == A2TB2);
2981 /* Calculation is done in real to avoid integer overflow. */
2983 inline_limit = gfc_get_constant_expr (BT_REAL, gfc_default_real_kind,
2984 &a->where);
2985 mpfr_set_si (inline_limit->value.real, flag_inline_matmul_limit,
2986 GFC_RND_MODE);
2987 mpfr_pow_ui (inline_limit->value.real, inline_limit->value.real, 3,
2988 GFC_RND_MODE);
2990 a1 = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2991 a2 = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
2992 b2 = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2994 gfc_clear_ts (&ts);
2995 ts.type = BT_REAL;
2996 ts.kind = gfc_default_real_kind;
2997 gfc_convert_type_warn (a1, &ts, 2, 0);
2998 gfc_convert_type_warn (a2, &ts, 2, 0);
2999 gfc_convert_type_warn (b2, &ts, 2, 0);
3001 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
3002 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
3004 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
3005 gfc_simplify_expr (cond, 0);
3007 else_2 = XCNEW (gfc_code);
3008 else_2->op = EXEC_IF;
3009 else_2->loc = a->where;
3011 if_2 = XCNEW (gfc_code);
3012 if_2->op = EXEC_IF;
3013 if_2->expr1 = cond;
3014 if_2->loc = a->where;
3015 if_2->block = else_2;
3017 if_1 = XCNEW (gfc_code);
3018 if_1->op = EXEC_IF;
3019 if_1->block = if_2;
3020 if_1->loc = a->where;
3022 return if_1;
3026 /* Insert code to issue a runtime error if the expressions are not equal. */
3028 static gfc_code *
3029 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
3031 gfc_expr *cond;
3032 gfc_code *if_1, *if_2;
3033 gfc_code *c;
3034 gfc_actual_arglist *a1, *a2, *a3;
3036 gcc_assert (e1->where.lb);
3037 /* Build the call to runtime_error. */
3038 c = XCNEW (gfc_code);
3039 c->op = EXEC_CALL;
3040 c->loc = e1->where;
3042 /* Get a null-terminated message string. */
3044 a1 = gfc_get_actual_arglist ();
3045 a1->expr = gfc_get_character_expr (gfc_default_character_kind, &e1->where,
3046 msg, strlen(msg)+1);
3047 c->ext.actual = a1;
3049 /* Pass the value of the first expression. */
3050 a2 = gfc_get_actual_arglist ();
3051 a2->expr = gfc_copy_expr (e1);
3052 a1->next = a2;
3054 /* Pass the value of the second expression. */
3055 a3 = gfc_get_actual_arglist ();
3056 a3->expr = gfc_copy_expr (e2);
3057 a2->next = a3;
3059 gfc_check_fe_runtime_error (c->ext.actual);
3060 gfc_resolve_fe_runtime_error (c);
3062 if_2 = XCNEW (gfc_code);
3063 if_2->op = EXEC_IF;
3064 if_2->loc = e1->where;
3065 if_2->next = c;
3067 if_1 = XCNEW (gfc_code);
3068 if_1->op = EXEC_IF;
3069 if_1->block = if_2;
3070 if_1->loc = e1->where;
3072 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
3073 gfc_simplify_expr (cond, 0);
3074 if_2->expr1 = cond;
3076 return if_1;
3079 /* Handle matrix reallocation. Caller is responsible to insert into
3080 the code tree.
3082 For the two-dimensional case, build
3084 if (allocated(c)) then
3085 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
3086 deallocate(c)
3087 allocate (c(size(a,1), size(b,2)))
3088 end if
3089 else
3090 allocate (c(size(a,1),size(b,2)))
3091 end if
3093 and for the other cases correspondingly.
3096 static gfc_code *
3097 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
3098 enum matrix_case m_case)
3101 gfc_expr *allocated, *alloc_expr;
3102 gfc_code *if_alloc_1, *if_alloc_2, *if_size_1, *if_size_2;
3103 gfc_code *else_alloc;
3104 gfc_code *deallocate, *allocate1, *allocate_else;
3105 gfc_array_ref *ar;
3106 gfc_expr *cond, *ne1, *ne2;
3108 if (warn_realloc_lhs)
3109 gfc_warning (OPT_Wrealloc_lhs,
3110 "Code for reallocating the allocatable array at %L will "
3111 "be added", &c->where);
3113 alloc_expr = gfc_copy_expr (c);
3115 ar = gfc_find_array_ref (alloc_expr);
3116 gcc_assert (ar && ar->type == AR_FULL);
3118 /* c comes in as a full ref. Change it into a copy and make it into an
3119 element ref so it has the right form for for ALLOCATE. In the same
3120 switch statement, also generate the size comparison for the secod IF
3121 statement. */
3123 ar->type = AR_ELEMENT;
3125 switch (m_case)
3127 case A2B2:
3128 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3129 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3130 ne1 = build_logical_expr (INTRINSIC_NE,
3131 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3132 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
3133 ne2 = build_logical_expr (INTRINSIC_NE,
3134 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3135 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3136 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3137 break;
3139 case A2B2T:
3140 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3141 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
3143 ne1 = build_logical_expr (INTRINSIC_NE,
3144 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3145 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
3146 ne2 = build_logical_expr (INTRINSIC_NE,
3147 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3148 get_array_inq_function (GFC_ISYM_SIZE, b, 1));
3149 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3150 break;
3152 case A2TB2:
3154 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
3155 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3157 ne1 = build_logical_expr (INTRINSIC_NE,
3158 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3159 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3160 ne2 = build_logical_expr (INTRINSIC_NE,
3161 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3162 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3163 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3164 break;
3166 case A2B1:
3167 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3168 cond = build_logical_expr (INTRINSIC_NE,
3169 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3170 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3171 break;
3173 case A1B2:
3174 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3175 cond = build_logical_expr (INTRINSIC_NE,
3176 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3177 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3178 break;
3180 default:
3181 gcc_unreachable();
3185 gfc_simplify_expr (cond, 0);
3187 /* We need two identical allocate statements in two
3188 branches of the IF statement. */
3190 allocate1 = XCNEW (gfc_code);
3191 allocate1->op = EXEC_ALLOCATE;
3192 allocate1->ext.alloc.list = gfc_get_alloc ();
3193 allocate1->loc = c->where;
3194 allocate1->ext.alloc.list->expr = gfc_copy_expr (alloc_expr);
3196 allocate_else = XCNEW (gfc_code);
3197 allocate_else->op = EXEC_ALLOCATE;
3198 allocate_else->ext.alloc.list = gfc_get_alloc ();
3199 allocate_else->loc = c->where;
3200 allocate_else->ext.alloc.list->expr = alloc_expr;
3202 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
3203 "_gfortran_allocated", c->where,
3204 1, gfc_copy_expr (c));
3206 deallocate = XCNEW (gfc_code);
3207 deallocate->op = EXEC_DEALLOCATE;
3208 deallocate->ext.alloc.list = gfc_get_alloc ();
3209 deallocate->ext.alloc.list->expr = gfc_copy_expr (c);
3210 deallocate->next = allocate1;
3211 deallocate->loc = c->where;
3213 if_size_2 = XCNEW (gfc_code);
3214 if_size_2->op = EXEC_IF;
3215 if_size_2->expr1 = cond;
3216 if_size_2->loc = c->where;
3217 if_size_2->next = deallocate;
3219 if_size_1 = XCNEW (gfc_code);
3220 if_size_1->op = EXEC_IF;
3221 if_size_1->block = if_size_2;
3222 if_size_1->loc = c->where;
3224 else_alloc = XCNEW (gfc_code);
3225 else_alloc->op = EXEC_IF;
3226 else_alloc->loc = c->where;
3227 else_alloc->next = allocate_else;
3229 if_alloc_2 = XCNEW (gfc_code);
3230 if_alloc_2->op = EXEC_IF;
3231 if_alloc_2->expr1 = allocated;
3232 if_alloc_2->loc = c->where;
3233 if_alloc_2->next = if_size_1;
3234 if_alloc_2->block = else_alloc;
3236 if_alloc_1 = XCNEW (gfc_code);
3237 if_alloc_1->op = EXEC_IF;
3238 if_alloc_1->block = if_alloc_2;
3239 if_alloc_1->loc = c->where;
3241 return if_alloc_1;
3244 /* Callback function for has_function_or_op. */
3246 static int
3247 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
3248 void *data ATTRIBUTE_UNUSED)
3250 if ((*e) == 0)
3251 return 0;
3252 else
3253 return (*e)->expr_type == EXPR_FUNCTION
3254 || (*e)->expr_type == EXPR_OP;
3257 /* Returns true if the expression contains a function. */
3259 static bool
3260 has_function_or_op (gfc_expr **e)
3262 if (e == NULL)
3263 return false;
3264 else
3265 return gfc_expr_walker (e, is_function_or_op, NULL);
3268 /* Freeze (assign to a temporary variable) a single expression. */
3270 static void
3271 freeze_expr (gfc_expr **ep)
3273 gfc_expr *ne;
3274 if (has_function_or_op (ep))
3276 ne = create_var (*ep, "freeze");
3277 *ep = ne;
3281 /* Go through an expression's references and assign them to temporary
3282 variables if they contain functions. This is usually done prior to
3283 front-end scalarization to avoid multiple invocations of functions. */
3285 static void
3286 freeze_references (gfc_expr *e)
3288 gfc_ref *r;
3289 gfc_array_ref *ar;
3290 int i;
3292 for (r=e->ref; r; r=r->next)
3294 if (r->type == REF_SUBSTRING)
3296 if (r->u.ss.start != NULL)
3297 freeze_expr (&r->u.ss.start);
3299 if (r->u.ss.end != NULL)
3300 freeze_expr (&r->u.ss.end);
3302 else if (r->type == REF_ARRAY)
3304 ar = &r->u.ar;
3305 switch (ar->type)
3307 case AR_FULL:
3308 break;
3310 case AR_SECTION:
3311 for (i=0; i<ar->dimen; i++)
3313 if (ar->dimen_type[i] == DIMEN_RANGE)
3315 freeze_expr (&ar->start[i]);
3316 freeze_expr (&ar->end[i]);
3317 freeze_expr (&ar->stride[i]);
3319 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
3321 freeze_expr (&ar->start[i]);
3324 break;
3326 case AR_ELEMENT:
3327 for (i=0; i<ar->dimen; i++)
3328 freeze_expr (&ar->start[i]);
3329 break;
3331 default:
3332 break;
3338 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
3340 static gfc_expr *
3341 convert_to_index_kind (gfc_expr *e)
3343 gfc_expr *res;
3345 gcc_assert (e != NULL);
3347 res = gfc_copy_expr (e);
3349 gcc_assert (e->ts.type == BT_INTEGER);
3351 if (res->ts.kind != gfc_index_integer_kind)
3353 gfc_typespec ts;
3354 gfc_clear_ts (&ts);
3355 ts.type = BT_INTEGER;
3356 ts.kind = gfc_index_integer_kind;
3358 gfc_convert_type_warn (e, &ts, 2, 0);
3361 return res;
3364 /* Function to create a DO loop including creation of the
3365 iteration variable. gfc_expr are copied.*/
3367 static gfc_code *
3368 create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where,
3369 gfc_namespace *ns, char *vname)
3372 char name[GFC_MAX_SYMBOL_LEN +1];
3373 gfc_symtree *symtree;
3374 gfc_symbol *symbol;
3375 gfc_expr *i;
3376 gfc_code *n, *n2;
3378 /* Create an expression for the iteration variable. */
3379 if (vname)
3380 sprintf (name, "__var_%d_do_%s", var_num++, vname);
3381 else
3382 sprintf (name, "__var_%d_do", var_num++);
3385 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
3386 gcc_unreachable ();
3388 /* Create the loop variable. */
3390 symbol = symtree->n.sym;
3391 symbol->ts.type = BT_INTEGER;
3392 symbol->ts.kind = gfc_index_integer_kind;
3393 symbol->attr.flavor = FL_VARIABLE;
3394 symbol->attr.referenced = 1;
3395 symbol->attr.dimension = 0;
3396 symbol->attr.fe_temp = 1;
3397 gfc_commit_symbol (symbol);
3399 i = gfc_get_expr ();
3400 i->expr_type = EXPR_VARIABLE;
3401 i->ts = symbol->ts;
3402 i->rank = 0;
3403 i->where = *where;
3404 i->symtree = symtree;
3406 /* ... and the nested DO statements. */
3407 n = XCNEW (gfc_code);
3408 n->op = EXEC_DO;
3409 n->loc = *where;
3410 n->ext.iterator = gfc_get_iterator ();
3411 n->ext.iterator->var = i;
3412 n->ext.iterator->start = convert_to_index_kind (start);
3413 n->ext.iterator->end = convert_to_index_kind (end);
3414 if (step)
3415 n->ext.iterator->step = convert_to_index_kind (step);
3416 else
3417 n->ext.iterator->step = gfc_get_int_expr (gfc_index_integer_kind,
3418 where, 1);
3420 n2 = XCNEW (gfc_code);
3421 n2->op = EXEC_DO;
3422 n2->loc = *where;
3423 n2->next = NULL;
3424 n->block = n2;
3425 return n;
3428 /* Get the upper bound of the DO loops for matmul along a dimension. This
3429 is one-based. */
3431 static gfc_expr*
3432 get_size_m1 (gfc_expr *e, int dimen)
3434 mpz_t size;
3435 gfc_expr *res;
3437 if (gfc_array_dimen_size (e, dimen - 1, &size))
3439 res = gfc_get_constant_expr (BT_INTEGER,
3440 gfc_index_integer_kind, &e->where);
3441 mpz_sub_ui (res->value.integer, size, 1);
3442 mpz_clear (size);
3444 else
3446 res = get_operand (INTRINSIC_MINUS,
3447 get_array_inq_function (GFC_ISYM_SIZE, e, dimen),
3448 gfc_get_int_expr (gfc_index_integer_kind,
3449 &e->where, 1));
3450 gfc_simplify_expr (res, 0);
3453 return res;
3456 /* Function to return a scalarized expression. It is assumed that indices are
3457 zero based to make generation of DO loops easier. A zero as index will
3458 access the first element along a dimension. Single element references will
3459 be skipped. A NULL as an expression will be replaced by a full reference.
3460 This assumes that the index loops have gfc_index_integer_kind, and that all
3461 references have been frozen. */
3463 static gfc_expr*
3464 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
3466 gfc_array_ref *ar;
3467 int i;
3468 int rank;
3469 gfc_expr *e;
3470 int i_index;
3471 bool was_fullref;
3473 e = gfc_copy_expr(e_in);
3475 rank = e->rank;
3477 ar = gfc_find_array_ref (e);
3479 /* We scalarize count_index variables, reducing the rank by count_index. */
3481 e->rank = rank - count_index;
3483 was_fullref = ar->type == AR_FULL;
3485 if (e->rank == 0)
3486 ar->type = AR_ELEMENT;
3487 else
3488 ar->type = AR_SECTION;
3490 /* Loop over the indices. For each index, create the expression
3491 index * stride + lbound(e, dim). */
3493 i_index = 0;
3494 for (i=0; i < ar->dimen; i++)
3496 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
3498 if (index[i_index] != NULL)
3500 gfc_expr *lbound, *nindex;
3501 gfc_expr *loopvar;
3503 loopvar = gfc_copy_expr (index[i_index]);
3505 if (ar->stride[i])
3507 gfc_expr *tmp;
3509 tmp = gfc_copy_expr(ar->stride[i]);
3510 if (tmp->ts.kind != gfc_index_integer_kind)
3512 gfc_typespec ts;
3513 gfc_clear_ts (&ts);
3514 ts.type = BT_INTEGER;
3515 ts.kind = gfc_index_integer_kind;
3516 gfc_convert_type (tmp, &ts, 2);
3518 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
3520 else
3521 nindex = loopvar;
3523 /* Calculate the lower bound of the expression. */
3524 if (ar->start[i])
3526 lbound = gfc_copy_expr (ar->start[i]);
3527 if (lbound->ts.kind != gfc_index_integer_kind)
3529 gfc_typespec ts;
3530 gfc_clear_ts (&ts);
3531 ts.type = BT_INTEGER;
3532 ts.kind = gfc_index_integer_kind;
3533 gfc_convert_type (lbound, &ts, 2);
3537 else
3539 gfc_expr *lbound_e;
3540 gfc_ref *ref;
3542 lbound_e = gfc_copy_expr (e_in);
3544 for (ref = lbound_e->ref; ref; ref = ref->next)
3545 if (ref->type == REF_ARRAY
3546 && (ref->u.ar.type == AR_FULL
3547 || ref->u.ar.type == AR_SECTION))
3548 break;
3550 if (ref->next)
3552 gfc_free_ref_list (ref->next);
3553 ref->next = NULL;
3556 if (!was_fullref)
3558 /* Look at full individual sections, like a(:). The first index
3559 is the lbound of a full ref. */
3560 int j;
3561 gfc_array_ref *ar;
3563 ar = &ref->u.ar;
3564 ar->type = AR_FULL;
3565 for (j = 0; j < ar->dimen; j++)
3567 gfc_free_expr (ar->start[j]);
3568 ar->start[j] = NULL;
3569 gfc_free_expr (ar->end[j]);
3570 ar->end[j] = NULL;
3571 gfc_free_expr (ar->stride[j]);
3572 ar->stride[j] = NULL;
3575 /* We have to get rid of the shape, if there is one. Do
3576 so by freeing it and calling gfc_resolve to rebuild
3577 it, if necessary. */
3579 if (lbound_e->shape)
3580 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
3582 lbound_e->rank = ar->dimen;
3583 gfc_resolve_expr (lbound_e);
3585 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
3586 i + 1);
3587 gfc_free_expr (lbound_e);
3590 ar->dimen_type[i] = DIMEN_ELEMENT;
3592 gfc_free_expr (ar->start[i]);
3593 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
3595 gfc_free_expr (ar->end[i]);
3596 ar->end[i] = NULL;
3597 gfc_free_expr (ar->stride[i]);
3598 ar->stride[i] = NULL;
3599 gfc_simplify_expr (ar->start[i], 0);
3601 else if (was_fullref)
3603 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
3605 i_index ++;
3609 return e;
3612 /* Helper function to check for a dimen vector as subscript. */
3614 static bool
3615 has_dimen_vector_ref (gfc_expr *e)
3617 gfc_array_ref *ar;
3618 int i;
3620 ar = gfc_find_array_ref (e);
3621 gcc_assert (ar);
3622 if (ar->type == AR_FULL)
3623 return false;
3625 for (i=0; i<ar->dimen; i++)
3626 if (ar->dimen_type[i] == DIMEN_VECTOR)
3627 return true;
3629 return false;
3632 /* If handed an expression of the form
3634 TRANSPOSE(CONJG(A))
3636 check if A can be handled by matmul and return if there is an uneven number
3637 of CONJG calls. Return a pointer to the array when everything is OK, NULL
3638 otherwise. The caller has to check for the correct rank. */
3640 static gfc_expr*
3641 check_conjg_transpose_variable (gfc_expr *e, bool *conjg, bool *transpose)
3643 *conjg = false;
3644 *transpose = false;
3648 if (e->expr_type == EXPR_VARIABLE)
3650 gcc_assert (e->rank == 1 || e->rank == 2);
3651 return e;
3653 else if (e->expr_type == EXPR_FUNCTION)
3655 if (e->value.function.isym == NULL)
3656 return NULL;
3658 if (e->value.function.isym->id == GFC_ISYM_CONJG)
3659 *conjg = !*conjg;
3660 else if (e->value.function.isym->id == GFC_ISYM_TRANSPOSE)
3661 *transpose = !*transpose;
3662 else return NULL;
3664 else
3665 return NULL;
3667 e = e->value.function.actual->expr;
3669 while(1);
3671 return NULL;
3674 /* Inline assignments of the form c = matmul(a,b).
3675 Handle only the cases currently where b and c are rank-two arrays.
3677 This basically translates the code to
3679 BLOCK
3680 integer i,j,k
3681 c = 0
3682 do j=0, size(b,2)-1
3683 do k=0, size(a, 2)-1
3684 do i=0, size(a, 1)-1
3685 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
3686 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
3687 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
3688 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
3689 end do
3690 end do
3691 end do
3692 END BLOCK
3696 static int
3697 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
3698 void *data ATTRIBUTE_UNUSED)
3700 gfc_code *co = *c;
3701 gfc_expr *expr1, *expr2;
3702 gfc_expr *matrix_a, *matrix_b;
3703 gfc_actual_arglist *a, *b;
3704 gfc_code *do_1, *do_2, *do_3, *assign_zero, *assign_matmul;
3705 gfc_expr *zero_e;
3706 gfc_expr *u1, *u2, *u3;
3707 gfc_expr *list[2];
3708 gfc_expr *ascalar, *bscalar, *cscalar;
3709 gfc_expr *mult;
3710 gfc_expr *var_1, *var_2, *var_3;
3711 gfc_expr *zero;
3712 gfc_namespace *ns;
3713 gfc_intrinsic_op op_times, op_plus;
3714 enum matrix_case m_case;
3715 int i;
3716 gfc_code *if_limit = NULL;
3717 gfc_code **next_code_point;
3718 bool conjg_a, conjg_b, transpose_a, transpose_b;
3720 if (co->op != EXEC_ASSIGN)
3721 return 0;
3723 if (in_where)
3724 return 0;
3726 /* The BLOCKS generated for the temporary variables and FORALL don't
3727 mix. */
3728 if (forall_level > 0)
3729 return 0;
3731 /* For now don't do anything in OpenMP workshare, it confuses
3732 its translation, which expects only the allowed statements in there.
3733 We should figure out how to parallelize this eventually. */
3734 if (in_omp_workshare)
3735 return 0;
3737 expr1 = co->expr1;
3738 expr2 = co->expr2;
3739 if (expr2->expr_type != EXPR_FUNCTION
3740 || expr2->value.function.isym == NULL
3741 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
3742 return 0;
3744 current_code = c;
3745 inserted_block = NULL;
3746 changed_statement = NULL;
3748 a = expr2->value.function.actual;
3749 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
3750 if (matrix_a == NULL)
3751 return 0;
3753 b = a->next;
3754 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
3755 if (matrix_b == NULL)
3756 return 0;
3758 if (has_dimen_vector_ref (expr1) || has_dimen_vector_ref (matrix_a)
3759 || has_dimen_vector_ref (matrix_b))
3760 return 0;
3762 /* We do not handle data dependencies yet. */
3763 if (gfc_check_dependency (expr1, matrix_a, true)
3764 || gfc_check_dependency (expr1, matrix_b, true))
3765 return 0;
3767 m_case = none;
3768 if (matrix_a->rank == 2)
3770 if (transpose_a)
3772 if (matrix_b->rank == 2 && !transpose_b)
3773 m_case = A2TB2;
3775 else
3777 if (matrix_b->rank == 1)
3778 m_case = A2B1;
3779 else /* matrix_b->rank == 2 */
3781 if (transpose_b)
3782 m_case = A2B2T;
3783 else
3784 m_case = A2B2;
3788 else /* matrix_a->rank == 1 */
3790 if (matrix_b->rank == 2)
3792 if (!transpose_b)
3793 m_case = A1B2;
3797 if (m_case == none)
3798 return 0;
3800 ns = insert_block ();
3802 /* Assign the type of the zero expression for initializing the resulting
3803 array, and the expression (+ and * for real, integer and complex;
3804 .and. and .or for logical. */
3806 switch(expr1->ts.type)
3808 case BT_INTEGER:
3809 zero_e = gfc_get_int_expr (expr1->ts.kind, &expr1->where, 0);
3810 op_times = INTRINSIC_TIMES;
3811 op_plus = INTRINSIC_PLUS;
3812 break;
3814 case BT_LOGICAL:
3815 op_times = INTRINSIC_AND;
3816 op_plus = INTRINSIC_OR;
3817 zero_e = gfc_get_logical_expr (expr1->ts.kind, &expr1->where,
3819 break;
3820 case BT_REAL:
3821 zero_e = gfc_get_constant_expr (BT_REAL, expr1->ts.kind,
3822 &expr1->where);
3823 mpfr_set_si (zero_e->value.real, 0, GFC_RND_MODE);
3824 op_times = INTRINSIC_TIMES;
3825 op_plus = INTRINSIC_PLUS;
3826 break;
3828 case BT_COMPLEX:
3829 zero_e = gfc_get_constant_expr (BT_COMPLEX, expr1->ts.kind,
3830 &expr1->where);
3831 mpc_set_si_si (zero_e->value.complex, 0, 0, GFC_RND_MODE);
3832 op_times = INTRINSIC_TIMES;
3833 op_plus = INTRINSIC_PLUS;
3835 break;
3837 default:
3838 gcc_unreachable();
3841 current_code = &ns->code;
3843 /* Freeze the references, keeping track of how many temporary variables were
3844 created. */
3845 n_vars = 0;
3846 freeze_references (matrix_a);
3847 freeze_references (matrix_b);
3848 freeze_references (expr1);
3850 if (n_vars == 0)
3851 next_code_point = current_code;
3852 else
3854 next_code_point = &ns->code;
3855 for (i=0; i<n_vars; i++)
3856 next_code_point = &(*next_code_point)->next;
3859 /* Take care of the inline flag. If the limit check evaluates to a
3860 constant, dead code elimination will eliminate the unneeded branch. */
3862 if (m_case == A2B2 && flag_inline_matmul_limit > 0)
3864 if_limit = inline_limit_check (matrix_a, matrix_b, m_case);
3866 /* Insert the original statement into the else branch. */
3867 if_limit->block->block->next = co;
3868 co->next = NULL;
3870 /* ... and the new ones go into the original one. */
3871 *next_code_point = if_limit;
3872 next_code_point = &if_limit->block->next;
3875 assign_zero = XCNEW (gfc_code);
3876 assign_zero->op = EXEC_ASSIGN;
3877 assign_zero->loc = co->loc;
3878 assign_zero->expr1 = gfc_copy_expr (expr1);
3879 assign_zero->expr2 = zero_e;
3881 /* Handle the reallocation, if needed. */
3882 if (flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1))
3884 gfc_code *lhs_alloc;
3886 /* Only need to check a single dimension for the A2B2 case for
3887 bounds checking, the rest will be allocated. Also check this
3888 for A2B1. */
3890 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && (m_case == A2B2 || m_case == A2B1))
3892 gfc_code *test;
3893 gfc_expr *a2, *b1;
3895 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3896 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3897 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
3898 "in MATMUL intrinsic: Is %ld, should be %ld");
3899 *next_code_point = test;
3900 next_code_point = &test->next;
3904 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
3906 *next_code_point = lhs_alloc;
3907 next_code_point = &lhs_alloc->next;
3910 else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3912 gfc_code *test;
3913 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
3915 if (m_case == A2B2 || m_case == A2B1)
3917 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3918 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3919 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
3920 "in MATMUL intrinsic: Is %ld, should be %ld");
3921 *next_code_point = test;
3922 next_code_point = &test->next;
3924 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3925 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3927 if (m_case == A2B2)
3928 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3929 "MATMUL intrinsic for dimension 1: "
3930 "is %ld, should be %ld");
3931 else if (m_case == A2B1)
3932 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3933 "MATMUL intrinsic: "
3934 "is %ld, should be %ld");
3937 *next_code_point = test;
3938 next_code_point = &test->next;
3940 else if (m_case == A1B2)
3942 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3943 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3944 test = runtime_error_ne (b1, a1, "Dimension of array B incorrect "
3945 "in MATMUL intrinsic: Is %ld, should be %ld");
3946 *next_code_point = test;
3947 next_code_point = &test->next;
3949 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3950 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3952 test = runtime_error_ne (c1, b2, "Incorrect extent in return array in "
3953 "MATMUL intrinsic: "
3954 "is %ld, should be %ld");
3956 *next_code_point = test;
3957 next_code_point = &test->next;
3960 if (m_case == A2B2)
3962 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
3963 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3964 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
3965 "MATMUL intrinsic for dimension 2: is %ld, should be %ld");
3967 *next_code_point = test;
3968 next_code_point = &test->next;
3971 if (m_case == A2B2T)
3973 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3974 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3975 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3976 "MATMUL intrinsic for dimension 1: "
3977 "is %ld, should be %ld");
3979 *next_code_point = test;
3980 next_code_point = &test->next;
3982 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
3983 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3984 test = runtime_error_ne (c2, b1, "Incorrect extent in return array in "
3985 "MATMUL intrinsic for dimension 2: "
3986 "is %ld, should be %ld");
3987 *next_code_point = test;
3988 next_code_point = &test->next;
3990 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3991 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3993 test = runtime_error_ne (b2, a2, "Incorrect extent in argument B in "
3994 "MATMUL intrnisic for dimension 2: "
3995 "is %ld, should be %ld");
3996 *next_code_point = test;
3997 next_code_point = &test->next;
4001 if (m_case == A2TB2)
4003 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4004 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4006 test = runtime_error_ne (c1, a2, "Incorrect extent in return array in "
4007 "MATMUL intrinsic for dimension 1: "
4008 "is %ld, should be %ld");
4010 *next_code_point = test;
4011 next_code_point = &test->next;
4013 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4014 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4015 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
4016 "MATMUL intrinsic for dimension 2: "
4017 "is %ld, should be %ld");
4018 *next_code_point = test;
4019 next_code_point = &test->next;
4021 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4022 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4024 test = runtime_error_ne (b1, a1, "Incorrect extent in argument B in "
4025 "MATMUL intrnisic for dimension 2: "
4026 "is %ld, should be %ld");
4027 *next_code_point = test;
4028 next_code_point = &test->next;
4033 *next_code_point = assign_zero;
4035 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
4037 assign_matmul = XCNEW (gfc_code);
4038 assign_matmul->op = EXEC_ASSIGN;
4039 assign_matmul->loc = co->loc;
4041 /* Get the bounds for the loops, create them and create the scalarized
4042 expressions. */
4044 switch (m_case)
4046 case A2B2:
4047 inline_limit_check (matrix_a, matrix_b, m_case);
4049 u1 = get_size_m1 (matrix_b, 2);
4050 u2 = get_size_m1 (matrix_a, 2);
4051 u3 = get_size_m1 (matrix_a, 1);
4053 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4054 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4055 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4057 do_1->block->next = do_2;
4058 do_2->block->next = do_3;
4059 do_3->block->next = assign_matmul;
4061 var_1 = do_1->ext.iterator->var;
4062 var_2 = do_2->ext.iterator->var;
4063 var_3 = do_3->ext.iterator->var;
4065 list[0] = var_3;
4066 list[1] = var_1;
4067 cscalar = scalarized_expr (co->expr1, list, 2);
4069 list[0] = var_3;
4070 list[1] = var_2;
4071 ascalar = scalarized_expr (matrix_a, list, 2);
4073 list[0] = var_2;
4074 list[1] = var_1;
4075 bscalar = scalarized_expr (matrix_b, list, 2);
4077 break;
4079 case A2B2T:
4080 inline_limit_check (matrix_a, matrix_b, m_case);
4082 u1 = get_size_m1 (matrix_b, 1);
4083 u2 = get_size_m1 (matrix_a, 2);
4084 u3 = get_size_m1 (matrix_a, 1);
4086 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4087 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4088 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4090 do_1->block->next = do_2;
4091 do_2->block->next = do_3;
4092 do_3->block->next = assign_matmul;
4094 var_1 = do_1->ext.iterator->var;
4095 var_2 = do_2->ext.iterator->var;
4096 var_3 = do_3->ext.iterator->var;
4098 list[0] = var_3;
4099 list[1] = var_1;
4100 cscalar = scalarized_expr (co->expr1, list, 2);
4102 list[0] = var_3;
4103 list[1] = var_2;
4104 ascalar = scalarized_expr (matrix_a, list, 2);
4106 list[0] = var_1;
4107 list[1] = var_2;
4108 bscalar = scalarized_expr (matrix_b, list, 2);
4110 break;
4112 case A2TB2:
4113 inline_limit_check (matrix_a, matrix_b, m_case);
4115 u1 = get_size_m1 (matrix_a, 2);
4116 u2 = get_size_m1 (matrix_b, 2);
4117 u3 = get_size_m1 (matrix_a, 1);
4119 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4120 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4121 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4123 do_1->block->next = do_2;
4124 do_2->block->next = do_3;
4125 do_3->block->next = assign_matmul;
4127 var_1 = do_1->ext.iterator->var;
4128 var_2 = do_2->ext.iterator->var;
4129 var_3 = do_3->ext.iterator->var;
4131 list[0] = var_1;
4132 list[1] = var_2;
4133 cscalar = scalarized_expr (co->expr1, list, 2);
4135 list[0] = var_3;
4136 list[1] = var_1;
4137 ascalar = scalarized_expr (matrix_a, list, 2);
4139 list[0] = var_3;
4140 list[1] = var_2;
4141 bscalar = scalarized_expr (matrix_b, list, 2);
4143 break;
4145 case A2B1:
4146 u1 = get_size_m1 (matrix_b, 1);
4147 u2 = get_size_m1 (matrix_a, 1);
4149 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4150 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4152 do_1->block->next = do_2;
4153 do_2->block->next = assign_matmul;
4155 var_1 = do_1->ext.iterator->var;
4156 var_2 = do_2->ext.iterator->var;
4158 list[0] = var_2;
4159 cscalar = scalarized_expr (co->expr1, list, 1);
4161 list[0] = var_2;
4162 list[1] = var_1;
4163 ascalar = scalarized_expr (matrix_a, list, 2);
4165 list[0] = var_1;
4166 bscalar = scalarized_expr (matrix_b, list, 1);
4168 break;
4170 case A1B2:
4171 u1 = get_size_m1 (matrix_b, 2);
4172 u2 = get_size_m1 (matrix_a, 1);
4174 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4175 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4177 do_1->block->next = do_2;
4178 do_2->block->next = assign_matmul;
4180 var_1 = do_1->ext.iterator->var;
4181 var_2 = do_2->ext.iterator->var;
4183 list[0] = var_1;
4184 cscalar = scalarized_expr (co->expr1, list, 1);
4186 list[0] = var_2;
4187 ascalar = scalarized_expr (matrix_a, list, 1);
4189 list[0] = var_2;
4190 list[1] = var_1;
4191 bscalar = scalarized_expr (matrix_b, list, 2);
4193 break;
4195 default:
4196 gcc_unreachable();
4199 /* Build the conjg call around the variables. Set the typespec manually
4200 because gfc_build_intrinsic_call sometimes gets this wrong. */
4201 if (conjg_a)
4203 gfc_typespec ts;
4204 ts = matrix_a->ts;
4205 ascalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
4206 matrix_a->where, 1, ascalar);
4207 ascalar->ts = ts;
4210 if (conjg_b)
4212 gfc_typespec ts;
4213 ts = matrix_b->ts;
4214 bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
4215 matrix_b->where, 1, bscalar);
4216 bscalar->ts = ts;
4218 /* First loop comes after the zero assignment. */
4219 assign_zero->next = do_1;
4221 /* Build the assignment expression in the loop. */
4222 assign_matmul->expr1 = gfc_copy_expr (cscalar);
4224 mult = get_operand (op_times, ascalar, bscalar);
4225 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
4227 /* If we don't want to keep the original statement around in
4228 the else branch, we can free it. */
4230 if (if_limit == NULL)
4231 gfc_free_statements(co);
4232 else
4233 co->next = NULL;
4235 gfc_free_expr (zero);
4236 *walk_subtrees = 0;
4237 return 0;
4241 /* Code for index interchange for loops which are grouped together in DO
4242 CONCURRENT or FORALL statements. This is currently only applied if the
4243 iterations are grouped together in a single statement.
4245 For this transformation, it is assumed that memory access in strides is
4246 expensive, and that loops which access later indices (which access memory
4247 in bigger strides) should be moved to the first loops.
4249 For this, a loop over all the statements is executed, counting the times
4250 that the loop iteration values are accessed in each index. The loop
4251 indices are then sorted to minimize access to later indices from inner
4252 loops. */
4254 /* Type for holding index information. */
4256 typedef struct {
4257 gfc_symbol *sym;
4258 gfc_forall_iterator *fa;
4259 int num;
4260 int n[GFC_MAX_DIMENSIONS];
4261 } ind_type;
4263 /* Callback function to determine if an expression is the
4264 corresponding variable. */
4266 static int
4267 has_var (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
4269 gfc_expr *expr = *e;
4270 gfc_symbol *sym;
4272 if (expr->expr_type != EXPR_VARIABLE)
4273 return 0;
4275 sym = (gfc_symbol *) data;
4276 return sym == expr->symtree->n.sym;
4279 /* Callback function to calculate the cost of a certain index. */
4281 static int
4282 index_cost (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
4283 void *data)
4285 ind_type *ind;
4286 gfc_expr *expr;
4287 gfc_array_ref *ar;
4288 gfc_ref *ref;
4289 int i,j;
4291 expr = *e;
4292 if (expr->expr_type != EXPR_VARIABLE)
4293 return 0;
4295 ar = NULL;
4296 for (ref = expr->ref; ref; ref = ref->next)
4298 if (ref->type == REF_ARRAY)
4300 ar = &ref->u.ar;
4301 break;
4304 if (ar == NULL || ar->type != AR_ELEMENT)
4305 return 0;
4307 ind = (ind_type *) data;
4308 for (i = 0; i < ar->dimen; i++)
4310 for (j=0; ind[j].sym != NULL; j++)
4312 if (gfc_expr_walker (&ar->start[i], has_var, (void *) (ind[j].sym)))
4313 ind[j].n[i]++;
4316 return 0;
4319 /* Callback function for qsort, to sort the loop indices. */
4321 static int
4322 loop_comp (const void *e1, const void *e2)
4324 const ind_type *i1 = (const ind_type *) e1;
4325 const ind_type *i2 = (const ind_type *) e2;
4326 int i;
4328 for (i=GFC_MAX_DIMENSIONS-1; i >= 0; i--)
4330 if (i1->n[i] != i2->n[i])
4331 return i1->n[i] - i2->n[i];
4333 /* All other things being equal, let's not change the ordering. */
4334 return i2->num - i1->num;
4337 /* Main function to do the index interchange. */
4339 static int
4340 index_interchange (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
4341 void *data ATTRIBUTE_UNUSED)
4343 gfc_code *co;
4344 co = *c;
4345 int n_iter;
4346 gfc_forall_iterator *fa;
4347 ind_type *ind;
4348 int i, j;
4350 if (co->op != EXEC_FORALL && co->op != EXEC_DO_CONCURRENT)
4351 return 0;
4353 n_iter = 0;
4354 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4355 n_iter ++;
4357 /* Nothing to reorder. */
4358 if (n_iter < 2)
4359 return 0;
4361 ind = XALLOCAVEC (ind_type, n_iter + 1);
4363 i = 0;
4364 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4366 ind[i].sym = fa->var->symtree->n.sym;
4367 ind[i].fa = fa;
4368 for (j=0; j<GFC_MAX_DIMENSIONS; j++)
4369 ind[i].n[j] = 0;
4370 ind[i].num = i;
4371 i++;
4373 ind[n_iter].sym = NULL;
4374 ind[n_iter].fa = NULL;
4376 gfc_code_walker (c, gfc_dummy_code_callback, index_cost, (void *) ind);
4377 qsort ((void *) ind, n_iter, sizeof (ind_type), loop_comp);
4379 /* Do the actual index interchange. */
4380 co->ext.forall_iterator = fa = ind[0].fa;
4381 for (i=1; i<n_iter; i++)
4383 fa->next = ind[i].fa;
4384 fa = fa->next;
4386 fa->next = NULL;
4388 if (flag_warn_frontend_loop_interchange)
4390 for (i=1; i<n_iter; i++)
4392 if (ind[i-1].num > ind[i].num)
4394 gfc_warning (OPT_Wfrontend_loop_interchange,
4395 "Interchanging loops at %L", &co->loc);
4396 break;
4401 return 0;
4404 #define WALK_SUBEXPR(NODE) \
4405 do \
4407 result = gfc_expr_walker (&(NODE), exprfn, data); \
4408 if (result) \
4409 return result; \
4411 while (0)
4412 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
4414 /* Walk expression *E, calling EXPRFN on each expression in it. */
4417 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
4419 while (*e)
4421 int walk_subtrees = 1;
4422 gfc_actual_arglist *a;
4423 gfc_ref *r;
4424 gfc_constructor *c;
4426 int result = exprfn (e, &walk_subtrees, data);
4427 if (result)
4428 return result;
4429 if (walk_subtrees)
4430 switch ((*e)->expr_type)
4432 case EXPR_OP:
4433 WALK_SUBEXPR ((*e)->value.op.op1);
4434 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
4435 break;
4436 case EXPR_FUNCTION:
4437 for (a = (*e)->value.function.actual; a; a = a->next)
4438 WALK_SUBEXPR (a->expr);
4439 break;
4440 case EXPR_COMPCALL:
4441 case EXPR_PPC:
4442 WALK_SUBEXPR ((*e)->value.compcall.base_object);
4443 for (a = (*e)->value.compcall.actual; a; a = a->next)
4444 WALK_SUBEXPR (a->expr);
4445 break;
4447 case EXPR_STRUCTURE:
4448 case EXPR_ARRAY:
4449 for (c = gfc_constructor_first ((*e)->value.constructor); c;
4450 c = gfc_constructor_next (c))
4452 if (c->iterator == NULL)
4453 WALK_SUBEXPR (c->expr);
4454 else
4456 iterator_level ++;
4457 WALK_SUBEXPR (c->expr);
4458 iterator_level --;
4459 WALK_SUBEXPR (c->iterator->var);
4460 WALK_SUBEXPR (c->iterator->start);
4461 WALK_SUBEXPR (c->iterator->end);
4462 WALK_SUBEXPR (c->iterator->step);
4466 if ((*e)->expr_type != EXPR_ARRAY)
4467 break;
4469 /* Fall through to the variable case in order to walk the
4470 reference. */
4471 gcc_fallthrough ();
4473 case EXPR_SUBSTRING:
4474 case EXPR_VARIABLE:
4475 for (r = (*e)->ref; r; r = r->next)
4477 gfc_array_ref *ar;
4478 int i;
4480 switch (r->type)
4482 case REF_ARRAY:
4483 ar = &r->u.ar;
4484 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
4486 for (i=0; i< ar->dimen; i++)
4488 WALK_SUBEXPR (ar->start[i]);
4489 WALK_SUBEXPR (ar->end[i]);
4490 WALK_SUBEXPR (ar->stride[i]);
4494 break;
4496 case REF_SUBSTRING:
4497 WALK_SUBEXPR (r->u.ss.start);
4498 WALK_SUBEXPR (r->u.ss.end);
4499 break;
4501 case REF_COMPONENT:
4502 break;
4506 default:
4507 break;
4509 return 0;
4511 return 0;
4514 #define WALK_SUBCODE(NODE) \
4515 do \
4517 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
4518 if (result) \
4519 return result; \
4521 while (0)
4523 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
4524 on each expression in it. If any of the hooks returns non-zero, that
4525 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
4526 no subcodes or subexpressions are traversed. */
4529 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
4530 void *data)
4532 for (; *c; c = &(*c)->next)
4534 int walk_subtrees = 1;
4535 int result = codefn (c, &walk_subtrees, data);
4536 if (result)
4537 return result;
4539 if (walk_subtrees)
4541 gfc_code *b;
4542 gfc_actual_arglist *a;
4543 gfc_code *co;
4544 gfc_association_list *alist;
4545 bool saved_in_omp_workshare;
4546 bool saved_in_where;
4548 /* There might be statement insertions before the current code,
4549 which must not affect the expression walker. */
4551 co = *c;
4552 saved_in_omp_workshare = in_omp_workshare;
4553 saved_in_where = in_where;
4555 switch (co->op)
4558 case EXEC_BLOCK:
4559 WALK_SUBCODE (co->ext.block.ns->code);
4560 if (co->ext.block.assoc)
4562 bool saved_in_assoc_list = in_assoc_list;
4564 in_assoc_list = true;
4565 for (alist = co->ext.block.assoc; alist; alist = alist->next)
4566 WALK_SUBEXPR (alist->target);
4568 in_assoc_list = saved_in_assoc_list;
4571 break;
4573 case EXEC_DO:
4574 doloop_level ++;
4575 WALK_SUBEXPR (co->ext.iterator->var);
4576 WALK_SUBEXPR (co->ext.iterator->start);
4577 WALK_SUBEXPR (co->ext.iterator->end);
4578 WALK_SUBEXPR (co->ext.iterator->step);
4579 break;
4581 case EXEC_IF:
4582 if_level ++;
4583 break;
4585 case EXEC_WHERE:
4586 in_where = true;
4587 break;
4589 case EXEC_CALL:
4590 case EXEC_ASSIGN_CALL:
4591 for (a = co->ext.actual; a; a = a->next)
4592 WALK_SUBEXPR (a->expr);
4593 break;
4595 case EXEC_CALL_PPC:
4596 WALK_SUBEXPR (co->expr1);
4597 for (a = co->ext.actual; a; a = a->next)
4598 WALK_SUBEXPR (a->expr);
4599 break;
4601 case EXEC_SELECT:
4602 WALK_SUBEXPR (co->expr1);
4603 select_level ++;
4604 for (b = co->block; b; b = b->block)
4606 gfc_case *cp;
4607 for (cp = b->ext.block.case_list; cp; cp = cp->next)
4609 WALK_SUBEXPR (cp->low);
4610 WALK_SUBEXPR (cp->high);
4612 WALK_SUBCODE (b->next);
4614 continue;
4616 case EXEC_ALLOCATE:
4617 case EXEC_DEALLOCATE:
4619 gfc_alloc *a;
4620 for (a = co->ext.alloc.list; a; a = a->next)
4621 WALK_SUBEXPR (a->expr);
4622 break;
4625 case EXEC_FORALL:
4626 case EXEC_DO_CONCURRENT:
4628 gfc_forall_iterator *fa;
4629 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4631 WALK_SUBEXPR (fa->var);
4632 WALK_SUBEXPR (fa->start);
4633 WALK_SUBEXPR (fa->end);
4634 WALK_SUBEXPR (fa->stride);
4636 if (co->op == EXEC_FORALL)
4637 forall_level ++;
4638 break;
4641 case EXEC_OPEN:
4642 WALK_SUBEXPR (co->ext.open->unit);
4643 WALK_SUBEXPR (co->ext.open->file);
4644 WALK_SUBEXPR (co->ext.open->status);
4645 WALK_SUBEXPR (co->ext.open->access);
4646 WALK_SUBEXPR (co->ext.open->form);
4647 WALK_SUBEXPR (co->ext.open->recl);
4648 WALK_SUBEXPR (co->ext.open->blank);
4649 WALK_SUBEXPR (co->ext.open->position);
4650 WALK_SUBEXPR (co->ext.open->action);
4651 WALK_SUBEXPR (co->ext.open->delim);
4652 WALK_SUBEXPR (co->ext.open->pad);
4653 WALK_SUBEXPR (co->ext.open->iostat);
4654 WALK_SUBEXPR (co->ext.open->iomsg);
4655 WALK_SUBEXPR (co->ext.open->convert);
4656 WALK_SUBEXPR (co->ext.open->decimal);
4657 WALK_SUBEXPR (co->ext.open->encoding);
4658 WALK_SUBEXPR (co->ext.open->round);
4659 WALK_SUBEXPR (co->ext.open->sign);
4660 WALK_SUBEXPR (co->ext.open->asynchronous);
4661 WALK_SUBEXPR (co->ext.open->id);
4662 WALK_SUBEXPR (co->ext.open->newunit);
4663 WALK_SUBEXPR (co->ext.open->share);
4664 WALK_SUBEXPR (co->ext.open->cc);
4665 break;
4667 case EXEC_CLOSE:
4668 WALK_SUBEXPR (co->ext.close->unit);
4669 WALK_SUBEXPR (co->ext.close->status);
4670 WALK_SUBEXPR (co->ext.close->iostat);
4671 WALK_SUBEXPR (co->ext.close->iomsg);
4672 break;
4674 case EXEC_BACKSPACE:
4675 case EXEC_ENDFILE:
4676 case EXEC_REWIND:
4677 case EXEC_FLUSH:
4678 WALK_SUBEXPR (co->ext.filepos->unit);
4679 WALK_SUBEXPR (co->ext.filepos->iostat);
4680 WALK_SUBEXPR (co->ext.filepos->iomsg);
4681 break;
4683 case EXEC_INQUIRE:
4684 WALK_SUBEXPR (co->ext.inquire->unit);
4685 WALK_SUBEXPR (co->ext.inquire->file);
4686 WALK_SUBEXPR (co->ext.inquire->iomsg);
4687 WALK_SUBEXPR (co->ext.inquire->iostat);
4688 WALK_SUBEXPR (co->ext.inquire->exist);
4689 WALK_SUBEXPR (co->ext.inquire->opened);
4690 WALK_SUBEXPR (co->ext.inquire->number);
4691 WALK_SUBEXPR (co->ext.inquire->named);
4692 WALK_SUBEXPR (co->ext.inquire->name);
4693 WALK_SUBEXPR (co->ext.inquire->access);
4694 WALK_SUBEXPR (co->ext.inquire->sequential);
4695 WALK_SUBEXPR (co->ext.inquire->direct);
4696 WALK_SUBEXPR (co->ext.inquire->form);
4697 WALK_SUBEXPR (co->ext.inquire->formatted);
4698 WALK_SUBEXPR (co->ext.inquire->unformatted);
4699 WALK_SUBEXPR (co->ext.inquire->recl);
4700 WALK_SUBEXPR (co->ext.inquire->nextrec);
4701 WALK_SUBEXPR (co->ext.inquire->blank);
4702 WALK_SUBEXPR (co->ext.inquire->position);
4703 WALK_SUBEXPR (co->ext.inquire->action);
4704 WALK_SUBEXPR (co->ext.inquire->read);
4705 WALK_SUBEXPR (co->ext.inquire->write);
4706 WALK_SUBEXPR (co->ext.inquire->readwrite);
4707 WALK_SUBEXPR (co->ext.inquire->delim);
4708 WALK_SUBEXPR (co->ext.inquire->encoding);
4709 WALK_SUBEXPR (co->ext.inquire->pad);
4710 WALK_SUBEXPR (co->ext.inquire->iolength);
4711 WALK_SUBEXPR (co->ext.inquire->convert);
4712 WALK_SUBEXPR (co->ext.inquire->strm_pos);
4713 WALK_SUBEXPR (co->ext.inquire->asynchronous);
4714 WALK_SUBEXPR (co->ext.inquire->decimal);
4715 WALK_SUBEXPR (co->ext.inquire->pending);
4716 WALK_SUBEXPR (co->ext.inquire->id);
4717 WALK_SUBEXPR (co->ext.inquire->sign);
4718 WALK_SUBEXPR (co->ext.inquire->size);
4719 WALK_SUBEXPR (co->ext.inquire->round);
4720 break;
4722 case EXEC_WAIT:
4723 WALK_SUBEXPR (co->ext.wait->unit);
4724 WALK_SUBEXPR (co->ext.wait->iostat);
4725 WALK_SUBEXPR (co->ext.wait->iomsg);
4726 WALK_SUBEXPR (co->ext.wait->id);
4727 break;
4729 case EXEC_READ:
4730 case EXEC_WRITE:
4731 WALK_SUBEXPR (co->ext.dt->io_unit);
4732 WALK_SUBEXPR (co->ext.dt->format_expr);
4733 WALK_SUBEXPR (co->ext.dt->rec);
4734 WALK_SUBEXPR (co->ext.dt->advance);
4735 WALK_SUBEXPR (co->ext.dt->iostat);
4736 WALK_SUBEXPR (co->ext.dt->size);
4737 WALK_SUBEXPR (co->ext.dt->iomsg);
4738 WALK_SUBEXPR (co->ext.dt->id);
4739 WALK_SUBEXPR (co->ext.dt->pos);
4740 WALK_SUBEXPR (co->ext.dt->asynchronous);
4741 WALK_SUBEXPR (co->ext.dt->blank);
4742 WALK_SUBEXPR (co->ext.dt->decimal);
4743 WALK_SUBEXPR (co->ext.dt->delim);
4744 WALK_SUBEXPR (co->ext.dt->pad);
4745 WALK_SUBEXPR (co->ext.dt->round);
4746 WALK_SUBEXPR (co->ext.dt->sign);
4747 WALK_SUBEXPR (co->ext.dt->extra_comma);
4748 break;
4750 case EXEC_OMP_PARALLEL:
4751 case EXEC_OMP_PARALLEL_DO:
4752 case EXEC_OMP_PARALLEL_DO_SIMD:
4753 case EXEC_OMP_PARALLEL_SECTIONS:
4755 in_omp_workshare = false;
4757 /* This goto serves as a shortcut to avoid code
4758 duplication or a larger if or switch statement. */
4759 goto check_omp_clauses;
4761 case EXEC_OMP_WORKSHARE:
4762 case EXEC_OMP_PARALLEL_WORKSHARE:
4764 in_omp_workshare = true;
4766 /* Fall through */
4768 case EXEC_OMP_CRITICAL:
4769 case EXEC_OMP_DISTRIBUTE:
4770 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
4771 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
4772 case EXEC_OMP_DISTRIBUTE_SIMD:
4773 case EXEC_OMP_DO:
4774 case EXEC_OMP_DO_SIMD:
4775 case EXEC_OMP_ORDERED:
4776 case EXEC_OMP_SECTIONS:
4777 case EXEC_OMP_SINGLE:
4778 case EXEC_OMP_END_SINGLE:
4779 case EXEC_OMP_SIMD:
4780 case EXEC_OMP_TASKLOOP:
4781 case EXEC_OMP_TASKLOOP_SIMD:
4782 case EXEC_OMP_TARGET:
4783 case EXEC_OMP_TARGET_DATA:
4784 case EXEC_OMP_TARGET_ENTER_DATA:
4785 case EXEC_OMP_TARGET_EXIT_DATA:
4786 case EXEC_OMP_TARGET_PARALLEL:
4787 case EXEC_OMP_TARGET_PARALLEL_DO:
4788 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
4789 case EXEC_OMP_TARGET_SIMD:
4790 case EXEC_OMP_TARGET_TEAMS:
4791 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4792 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
4793 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4794 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
4795 case EXEC_OMP_TARGET_UPDATE:
4796 case EXEC_OMP_TASK:
4797 case EXEC_OMP_TEAMS:
4798 case EXEC_OMP_TEAMS_DISTRIBUTE:
4799 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
4800 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4801 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
4803 /* Come to this label only from the
4804 EXEC_OMP_PARALLEL_* cases above. */
4806 check_omp_clauses:
4808 if (co->ext.omp_clauses)
4810 gfc_omp_namelist *n;
4811 static int list_types[]
4812 = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
4813 OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
4814 size_t idx;
4815 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
4816 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
4817 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
4818 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
4819 WALK_SUBEXPR (co->ext.omp_clauses->safelen_expr);
4820 WALK_SUBEXPR (co->ext.omp_clauses->simdlen_expr);
4821 WALK_SUBEXPR (co->ext.omp_clauses->num_teams);
4822 WALK_SUBEXPR (co->ext.omp_clauses->device);
4823 WALK_SUBEXPR (co->ext.omp_clauses->thread_limit);
4824 WALK_SUBEXPR (co->ext.omp_clauses->dist_chunk_size);
4825 WALK_SUBEXPR (co->ext.omp_clauses->grainsize);
4826 WALK_SUBEXPR (co->ext.omp_clauses->hint);
4827 WALK_SUBEXPR (co->ext.omp_clauses->num_tasks);
4828 WALK_SUBEXPR (co->ext.omp_clauses->priority);
4829 for (idx = 0; idx < OMP_IF_LAST; idx++)
4830 WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
4831 for (idx = 0;
4832 idx < sizeof (list_types) / sizeof (list_types[0]);
4833 idx++)
4834 for (n = co->ext.omp_clauses->lists[list_types[idx]];
4835 n; n = n->next)
4836 WALK_SUBEXPR (n->expr);
4838 break;
4839 default:
4840 break;
4843 WALK_SUBEXPR (co->expr1);
4844 WALK_SUBEXPR (co->expr2);
4845 WALK_SUBEXPR (co->expr3);
4846 WALK_SUBEXPR (co->expr4);
4847 for (b = co->block; b; b = b->block)
4849 WALK_SUBEXPR (b->expr1);
4850 WALK_SUBEXPR (b->expr2);
4851 WALK_SUBCODE (b->next);
4854 if (co->op == EXEC_FORALL)
4855 forall_level --;
4857 if (co->op == EXEC_DO)
4858 doloop_level --;
4860 if (co->op == EXEC_IF)
4861 if_level --;
4863 if (co->op == EXEC_SELECT)
4864 select_level --;
4866 in_omp_workshare = saved_in_omp_workshare;
4867 in_where = saved_in_where;
4870 return 0;