re PR fortran/91390 (treatment of extra parameter in a subroutine call)
[official-gcc.git] / gcc / fortran / frontend-passes.c
blob86debab05996b9f527d1cbda4d1113d0136c746d
1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2019 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 int call_external_blas (gfc_code **, int *, void *);
57 static int matmul_temp_args (gfc_code **, int *,void *data);
58 static int index_interchange (gfc_code **, int*, void *);
59 static bool is_fe_temp (gfc_expr *e);
61 #ifdef CHECKING_P
62 static void check_locus (gfc_namespace *);
63 #endif
65 /* How deep we are inside an argument list. */
67 static int count_arglist;
69 /* Vector of gfc_expr ** we operate on. */
71 static vec<gfc_expr **> expr_array;
73 /* Pointer to the gfc_code we currently work on - to be able to insert
74 a block before the statement. */
76 static gfc_code **current_code;
78 /* Pointer to the block to be inserted, and the statement we are
79 changing within the block. */
81 static gfc_code *inserted_block, **changed_statement;
83 /* The namespace we are currently dealing with. */
85 static gfc_namespace *current_ns;
87 /* If we are within any forall loop. */
89 static int forall_level;
91 /* Keep track of whether we are within an OMP workshare. */
93 static bool in_omp_workshare;
95 /* Keep track of whether we are within a WHERE statement. */
97 static bool in_where;
99 /* Keep track of iterators for array constructors. */
101 static int iterator_level;
103 /* Keep track of DO loop levels. */
105 typedef struct {
106 gfc_code *c;
107 int branch_level;
108 bool seen_goto;
109 } do_t;
111 static vec<do_t> doloop_list;
112 static int doloop_level;
114 /* Keep track of if and select case levels. */
116 static int if_level;
117 static int select_level;
119 /* Vector of gfc_expr * to keep track of DO loops. */
121 struct my_struct *evec;
123 /* Keep track of association lists. */
125 static bool in_assoc_list;
127 /* Counter for temporary variables. */
129 static int var_num = 1;
131 /* What sort of matrix we are dealing with when inlining MATMUL. */
133 enum matrix_case { none=0, A2B2, A2B1, A1B2, A2B2T, A2TB2, A2TB2T };
135 /* Keep track of the number of expressions we have inserted so far
136 using create_var. */
138 int n_vars;
140 /* Entry point - run all passes for a namespace. */
142 void
143 gfc_run_passes (gfc_namespace *ns)
146 /* Warn about dubious DO loops where the index might
147 change. */
149 doloop_level = 0;
150 if_level = 0;
151 select_level = 0;
152 doloop_warn (ns);
153 doloop_list.release ();
154 int w, e;
156 #ifdef CHECKING_P
157 check_locus (ns);
158 #endif
160 gfc_get_errors (&w, &e);
161 if (e > 0)
162 return;
164 if (flag_frontend_optimize || flag_frontend_loop_interchange)
165 optimize_namespace (ns);
167 if (flag_frontend_optimize)
169 optimize_reduction (ns);
170 if (flag_dump_fortran_optimized)
171 gfc_dump_parse_tree (ns, stdout);
173 expr_array.release ();
176 if (flag_realloc_lhs)
177 realloc_strings (ns);
180 #ifdef CHECKING_P
182 /* Callback function: Warn if there is no location information in a
183 statement. */
185 static int
186 check_locus_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
187 void *data ATTRIBUTE_UNUSED)
189 current_code = c;
190 if (c && *c && (((*c)->loc.nextc == NULL) || ((*c)->loc.lb == NULL)))
191 gfc_warning_internal (0, "Inconsistent internal state: "
192 "No location in statement");
194 return 0;
198 /* Callback function: Warn if there is no location information in an
199 expression. */
201 static int
202 check_locus_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
203 void *data ATTRIBUTE_UNUSED)
206 if (e && *e && (((*e)->where.nextc == NULL || (*e)->where.lb == NULL)))
207 gfc_warning_internal (0, "Inconsistent internal state: "
208 "No location in expression near %L",
209 &((*current_code)->loc));
210 return 0;
213 /* Run check for missing location information. */
215 static void
216 check_locus (gfc_namespace *ns)
218 gfc_code_walker (&ns->code, check_locus_code, check_locus_expr, NULL);
220 for (ns = ns->contained; ns; ns = ns->sibling)
222 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
223 check_locus (ns);
227 #endif
229 /* Callback for each gfc_code node invoked from check_realloc_strings.
230 For an allocatable LHS string which also appears as a variable on
231 the RHS, replace
233 a = a(x:y)
235 with
237 tmp = a(x:y)
238 a = tmp
241 static int
242 realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
243 void *data ATTRIBUTE_UNUSED)
245 gfc_expr *expr1, *expr2;
246 gfc_code *co = *c;
247 gfc_expr *n;
248 gfc_ref *ref;
249 bool found_substr;
251 if (co->op != EXEC_ASSIGN)
252 return 0;
254 expr1 = co->expr1;
255 if (expr1->ts.type != BT_CHARACTER
256 || !gfc_expr_attr(expr1).allocatable
257 || !expr1->ts.deferred)
258 return 0;
260 if (is_fe_temp (expr1))
261 return 0;
263 expr2 = gfc_discard_nops (co->expr2);
265 if (expr2->expr_type == EXPR_VARIABLE)
267 found_substr = false;
268 for (ref = expr2->ref; ref; ref = ref->next)
270 if (ref->type == REF_SUBSTRING)
272 found_substr = true;
273 break;
276 if (!found_substr)
277 return 0;
279 else if (expr2->expr_type != EXPR_ARRAY
280 && (expr2->expr_type != EXPR_OP
281 || expr2->value.op.op != INTRINSIC_CONCAT))
282 return 0;
284 if (!gfc_check_dependency (expr1, expr2, true))
285 return 0;
287 /* gfc_check_dependency doesn't always pick up identical expressions.
288 However, eliminating the above sends the compiler into an infinite
289 loop on valid expressions. Without this check, the gimplifier emits
290 an ICE for a = a, where a is deferred character length. */
291 if (!gfc_dep_compare_expr (expr1, expr2))
292 return 0;
294 current_code = c;
295 inserted_block = NULL;
296 changed_statement = NULL;
297 n = create_var (expr2, "realloc_string");
298 co->expr2 = n;
299 return 0;
302 /* Callback for each gfc_code node invoked through gfc_code_walker
303 from optimize_namespace. */
305 static int
306 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
307 void *data ATTRIBUTE_UNUSED)
310 gfc_exec_op op;
312 op = (*c)->op;
314 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
315 || op == EXEC_CALL_PPC)
316 count_arglist = 1;
317 else
318 count_arglist = 0;
320 current_code = c;
321 inserted_block = NULL;
322 changed_statement = NULL;
324 if (op == EXEC_ASSIGN)
325 optimize_assignment (*c);
326 return 0;
329 /* Callback for each gfc_expr node invoked through gfc_code_walker
330 from optimize_namespace. */
332 static int
333 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
334 void *data ATTRIBUTE_UNUSED)
336 bool function_expr;
338 if ((*e)->expr_type == EXPR_FUNCTION)
340 count_arglist ++;
341 function_expr = true;
343 else
344 function_expr = false;
346 if (optimize_trim (*e))
347 gfc_simplify_expr (*e, 0);
349 if (optimize_lexical_comparison (*e))
350 gfc_simplify_expr (*e, 0);
352 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
353 gfc_simplify_expr (*e, 0);
355 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
356 switch ((*e)->value.function.isym->id)
358 case GFC_ISYM_MINLOC:
359 case GFC_ISYM_MAXLOC:
360 optimize_minmaxloc (e);
361 break;
362 default:
363 break;
366 if (function_expr)
367 count_arglist --;
369 return 0;
372 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
373 function is a scalar, just copy it; otherwise returns the new element, the
374 old one can be freed. */
376 static gfc_expr *
377 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
379 gfc_expr *fcn, *e = c->expr;
381 fcn = gfc_copy_expr (e);
382 if (c->iterator)
384 gfc_constructor_base newbase;
385 gfc_expr *new_expr;
386 gfc_constructor *new_c;
388 newbase = NULL;
389 new_expr = gfc_get_expr ();
390 new_expr->expr_type = EXPR_ARRAY;
391 new_expr->ts = e->ts;
392 new_expr->where = e->where;
393 new_expr->rank = 1;
394 new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
395 new_c->iterator = c->iterator;
396 new_expr->value.constructor = newbase;
397 c->iterator = NULL;
399 fcn = new_expr;
402 if (fcn->rank != 0)
404 gfc_isym_id id = fn->value.function.isym->id;
406 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
407 fcn = gfc_build_intrinsic_call (current_ns, id,
408 fn->value.function.isym->name,
409 fn->where, 3, fcn, NULL, NULL);
410 else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
411 fcn = gfc_build_intrinsic_call (current_ns, id,
412 fn->value.function.isym->name,
413 fn->where, 2, fcn, NULL);
414 else
415 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
417 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
420 return fcn;
423 /* Callback function for optimzation of reductions to scalars. Transform ANY
424 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
425 correspondingly. Handly only the simple cases without MASK and DIM. */
427 static int
428 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
429 void *data ATTRIBUTE_UNUSED)
431 gfc_expr *fn, *arg;
432 gfc_intrinsic_op op;
433 gfc_isym_id id;
434 gfc_actual_arglist *a;
435 gfc_actual_arglist *dim;
436 gfc_constructor *c;
437 gfc_expr *res, *new_expr;
438 gfc_actual_arglist *mask;
440 fn = *e;
442 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
443 || fn->value.function.isym == NULL)
444 return 0;
446 id = fn->value.function.isym->id;
448 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
449 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
450 return 0;
452 a = fn->value.function.actual;
454 /* Don't handle MASK or DIM. */
456 dim = a->next;
458 if (dim->expr != NULL)
459 return 0;
461 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
463 mask = dim->next;
464 if ( mask->expr != NULL)
465 return 0;
468 arg = a->expr;
470 if (arg->expr_type != EXPR_ARRAY)
471 return 0;
473 switch (id)
475 case GFC_ISYM_SUM:
476 op = INTRINSIC_PLUS;
477 break;
479 case GFC_ISYM_PRODUCT:
480 op = INTRINSIC_TIMES;
481 break;
483 case GFC_ISYM_ANY:
484 op = INTRINSIC_OR;
485 break;
487 case GFC_ISYM_ALL:
488 op = INTRINSIC_AND;
489 break;
491 default:
492 return 0;
495 c = gfc_constructor_first (arg->value.constructor);
497 /* Don't do any simplififcation if we have
498 - no element in the constructor or
499 - only have a single element in the array which contains an
500 iterator. */
502 if (c == NULL)
503 return 0;
505 res = copy_walk_reduction_arg (c, fn);
507 c = gfc_constructor_next (c);
508 while (c)
510 new_expr = gfc_get_expr ();
511 new_expr->ts = fn->ts;
512 new_expr->expr_type = EXPR_OP;
513 new_expr->rank = fn->rank;
514 new_expr->where = fn->where;
515 new_expr->value.op.op = op;
516 new_expr->value.op.op1 = res;
517 new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
518 res = new_expr;
519 c = gfc_constructor_next (c);
522 gfc_simplify_expr (res, 0);
523 *e = res;
524 gfc_free_expr (fn);
526 return 0;
529 /* Callback function for common function elimination, called from cfe_expr_0.
530 Put all eligible function expressions into expr_array. */
532 static int
533 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
534 void *data ATTRIBUTE_UNUSED)
537 if ((*e)->expr_type != EXPR_FUNCTION)
538 return 0;
540 /* We don't do character functions with unknown charlens. */
541 if ((*e)->ts.type == BT_CHARACTER
542 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
543 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
544 return 0;
546 /* We don't do function elimination within FORALL statements, it can
547 lead to wrong-code in certain circumstances. */
549 if (forall_level > 0)
550 return 0;
552 /* Function elimination inside an iterator could lead to functions which
553 depend on iterator variables being moved outside. FIXME: We should check
554 if the functions do indeed depend on the iterator variable. */
556 if (iterator_level > 0)
557 return 0;
559 /* If we don't know the shape at compile time, we create an allocatable
560 temporary variable to hold the intermediate result, but only if
561 allocation on assignment is active. */
563 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
564 return 0;
566 /* Skip the test for pure functions if -faggressive-function-elimination
567 is specified. */
568 if ((*e)->value.function.esym)
570 /* Don't create an array temporary for elemental functions. */
571 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
572 return 0;
574 /* Only eliminate potentially impure functions if the
575 user specifically requested it. */
576 if (!flag_aggressive_function_elimination
577 && !(*e)->value.function.esym->attr.pure
578 && !(*e)->value.function.esym->attr.implicit_pure)
579 return 0;
582 if ((*e)->value.function.isym)
584 /* Conversions are handled on the fly by the middle end,
585 transpose during trans-* stages and TRANSFER by the middle end. */
586 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
587 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
588 || gfc_inline_intrinsic_function_p (*e))
589 return 0;
591 /* Don't create an array temporary for elemental functions,
592 as this would be wasteful of memory.
593 FIXME: Create a scalar temporary during scalarization. */
594 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
595 return 0;
597 if (!(*e)->value.function.isym->pure)
598 return 0;
601 expr_array.safe_push (e);
602 return 0;
605 /* Auxiliary function to check if an expression is a temporary created by
606 create var. */
608 static bool
609 is_fe_temp (gfc_expr *e)
611 if (e->expr_type != EXPR_VARIABLE)
612 return false;
614 return e->symtree->n.sym->attr.fe_temp;
617 /* Determine the length of a string, if it can be evaluated as a constant
618 expression. Return a newly allocated gfc_expr or NULL on failure.
619 If the user specified a substring which is potentially longer than
620 the string itself, the string will be padded with spaces, which
621 is harmless. */
623 static gfc_expr *
624 constant_string_length (gfc_expr *e)
627 gfc_expr *length;
628 gfc_ref *ref;
629 gfc_expr *res;
630 mpz_t value;
632 if (e->ts.u.cl)
634 length = e->ts.u.cl->length;
635 if (length && length->expr_type == EXPR_CONSTANT)
636 return gfc_copy_expr(length);
639 /* See if there is a substring. If it has a constant length, return
640 that and NULL otherwise. */
641 for (ref = e->ref; ref; ref = ref->next)
643 if (ref->type == REF_SUBSTRING)
645 if (gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
647 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
648 &e->where);
650 mpz_add_ui (res->value.integer, value, 1);
651 mpz_clear (value);
652 return res;
654 else
655 return NULL;
659 /* Return length of char symbol, if constant. */
660 if (e->symtree && e->symtree->n.sym->ts.u.cl
661 && e->symtree->n.sym->ts.u.cl->length
662 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
663 return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length);
665 return NULL;
669 /* Insert a block at the current position unless it has already
670 been inserted; in this case use the one already there. */
672 static gfc_namespace*
673 insert_block ()
675 gfc_namespace *ns;
677 /* If the block hasn't already been created, do so. */
678 if (inserted_block == NULL)
680 inserted_block = XCNEW (gfc_code);
681 inserted_block->op = EXEC_BLOCK;
682 inserted_block->loc = (*current_code)->loc;
683 ns = gfc_build_block_ns (current_ns);
684 inserted_block->ext.block.ns = ns;
685 inserted_block->ext.block.assoc = NULL;
687 ns->code = *current_code;
689 /* If the statement has a label, make sure it is transferred to
690 the newly created block. */
692 if ((*current_code)->here)
694 inserted_block->here = (*current_code)->here;
695 (*current_code)->here = NULL;
698 inserted_block->next = (*current_code)->next;
699 changed_statement = &(inserted_block->ext.block.ns->code);
700 (*current_code)->next = NULL;
701 /* Insert the BLOCK at the right position. */
702 *current_code = inserted_block;
703 ns->parent = current_ns;
705 else
706 ns = inserted_block->ext.block.ns;
708 return ns;
712 /* Insert a call to the intrinsic len. Use a different name for
713 the symbol tree so we don't run into trouble when the user has
714 renamed len for some reason. */
716 static gfc_expr*
717 get_len_call (gfc_expr *str)
719 gfc_expr *fcn;
720 gfc_actual_arglist *actual_arglist;
722 fcn = gfc_get_expr ();
723 fcn->expr_type = EXPR_FUNCTION;
724 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN);
725 actual_arglist = gfc_get_actual_arglist ();
726 actual_arglist->expr = str;
728 fcn->value.function.actual = actual_arglist;
729 fcn->where = str->where;
730 fcn->ts.type = BT_INTEGER;
731 fcn->ts.kind = gfc_charlen_int_kind;
733 gfc_get_sym_tree ("__internal_len", current_ns, &fcn->symtree, false);
734 fcn->symtree->n.sym->ts = fcn->ts;
735 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
736 fcn->symtree->n.sym->attr.function = 1;
737 fcn->symtree->n.sym->attr.elemental = 1;
738 fcn->symtree->n.sym->attr.referenced = 1;
739 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
740 gfc_commit_symbol (fcn->symtree->n.sym);
742 return fcn;
746 /* Returns a new expression (a variable) to be used in place of the old one,
747 with an optional assignment statement before the current statement to set
748 the value of the variable. Creates a new BLOCK for the statement if that
749 hasn't already been done and puts the statement, plus the newly created
750 variables, in that block. Special cases: If the expression is constant or
751 a temporary which has already been created, just copy it. */
753 static gfc_expr*
754 create_var (gfc_expr * e, const char *vname)
756 char name[GFC_MAX_SYMBOL_LEN +1];
757 gfc_symtree *symtree;
758 gfc_symbol *symbol;
759 gfc_expr *result;
760 gfc_code *n;
761 gfc_namespace *ns;
762 int i;
763 bool deferred;
765 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
766 return gfc_copy_expr (e);
768 /* Creation of an array of unknown size requires realloc on assignment.
769 If that is not possible, just return NULL. */
770 if (flag_realloc_lhs == 0 && e->rank > 0 && e->shape == NULL)
771 return NULL;
773 ns = insert_block ();
775 if (vname)
776 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d_%s", var_num++, vname);
777 else
778 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d", var_num++);
780 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
781 gcc_unreachable ();
783 symbol = symtree->n.sym;
784 symbol->ts = e->ts;
786 if (e->rank > 0)
788 symbol->as = gfc_get_array_spec ();
789 symbol->as->rank = e->rank;
791 if (e->shape == NULL)
793 /* We don't know the shape at compile time, so we use an
794 allocatable. */
795 symbol->as->type = AS_DEFERRED;
796 symbol->attr.allocatable = 1;
798 else
800 symbol->as->type = AS_EXPLICIT;
801 /* Copy the shape. */
802 for (i=0; i<e->rank; i++)
804 gfc_expr *p, *q;
806 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
807 &(e->where));
808 mpz_set_si (p->value.integer, 1);
809 symbol->as->lower[i] = p;
811 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
812 &(e->where));
813 mpz_set (q->value.integer, e->shape[i]);
814 symbol->as->upper[i] = q;
819 deferred = 0;
820 if (e->ts.type == BT_CHARACTER)
822 gfc_expr *length;
824 symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
825 length = constant_string_length (e);
826 if (length)
827 symbol->ts.u.cl->length = length;
828 else if (e->expr_type == EXPR_VARIABLE
829 && e->symtree->n.sym->ts.type == BT_CHARACTER
830 && e->ts.u.cl->length)
831 symbol->ts.u.cl->length = get_len_call (gfc_copy_expr (e));
832 else
834 symbol->attr.allocatable = 1;
835 symbol->ts.u.cl->length = NULL;
836 symbol->ts.deferred = 1;
837 deferred = 1;
841 symbol->attr.flavor = FL_VARIABLE;
842 symbol->attr.referenced = 1;
843 symbol->attr.dimension = e->rank > 0;
844 symbol->attr.fe_temp = 1;
845 gfc_commit_symbol (symbol);
847 result = gfc_get_expr ();
848 result->expr_type = EXPR_VARIABLE;
849 result->ts = symbol->ts;
850 result->ts.deferred = deferred;
851 result->rank = e->rank;
852 result->shape = gfc_copy_shape (e->shape, e->rank);
853 result->symtree = symtree;
854 result->where = e->where;
855 if (e->rank > 0)
857 result->ref = gfc_get_ref ();
858 result->ref->type = REF_ARRAY;
859 result->ref->u.ar.type = AR_FULL;
860 result->ref->u.ar.where = e->where;
861 result->ref->u.ar.dimen = e->rank;
862 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
863 ? CLASS_DATA (symbol)->as : symbol->as;
864 if (warn_array_temporaries)
865 gfc_warning (OPT_Warray_temporaries,
866 "Creating array temporary at %L", &(e->where));
869 /* Generate the new assignment. */
870 n = XCNEW (gfc_code);
871 n->op = EXEC_ASSIGN;
872 n->loc = (*current_code)->loc;
873 n->next = *changed_statement;
874 n->expr1 = gfc_copy_expr (result);
875 n->expr2 = e;
876 *changed_statement = n;
877 n_vars ++;
879 return result;
882 /* Warn about function elimination. */
884 static void
885 do_warn_function_elimination (gfc_expr *e)
887 const char *name;
888 if (e->expr_type == EXPR_FUNCTION
889 && !gfc_pure_function (e, &name) && !gfc_implicit_pure_function (e))
891 if (name)
892 gfc_warning (OPT_Wfunction_elimination,
893 "Removing call to impure function %qs at %L", name,
894 &(e->where));
895 else
896 gfc_warning (OPT_Wfunction_elimination,
897 "Removing call to impure function at %L",
898 &(e->where));
903 /* Callback function for the code walker for doing common function
904 elimination. This builds up the list of functions in the expression
905 and goes through them to detect duplicates, which it then replaces
906 by variables. */
908 static int
909 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
910 void *data ATTRIBUTE_UNUSED)
912 int i,j;
913 gfc_expr *newvar;
914 gfc_expr **ei, **ej;
916 /* Don't do this optimization within OMP workshare or ASSOC lists. */
918 if (in_omp_workshare || in_assoc_list)
920 *walk_subtrees = 0;
921 return 0;
924 expr_array.release ();
926 gfc_expr_walker (e, cfe_register_funcs, NULL);
928 /* Walk through all the functions. */
930 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
932 /* Skip if the function has been replaced by a variable already. */
933 if ((*ei)->expr_type == EXPR_VARIABLE)
934 continue;
936 newvar = NULL;
937 for (j=0; j<i; j++)
939 ej = expr_array[j];
940 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
942 if (newvar == NULL)
943 newvar = create_var (*ei, "fcn");
945 if (warn_function_elimination)
946 do_warn_function_elimination (*ej);
948 free (*ej);
949 *ej = gfc_copy_expr (newvar);
952 if (newvar)
953 *ei = newvar;
956 /* We did all the necessary walking in this function. */
957 *walk_subtrees = 0;
958 return 0;
961 /* Callback function for common function elimination, called from
962 gfc_code_walker. This keeps track of the current code, in order
963 to insert statements as needed. */
965 static int
966 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
968 current_code = c;
969 inserted_block = NULL;
970 changed_statement = NULL;
972 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
973 and allocation on assigment are prohibited inside WHERE, and finally
974 masking an expression would lead to wrong-code when replacing
976 WHERE (a>0)
977 b = sum(foo(a) + foo(a))
978 END WHERE
980 with
982 WHERE (a > 0)
983 tmp = foo(a)
984 b = sum(tmp + tmp)
985 END WHERE
988 if ((*c)->op == EXEC_WHERE)
990 *walk_subtrees = 0;
991 return 0;
995 return 0;
998 /* Dummy function for expression call back, for use when we
999 really don't want to do any walking. */
1001 static int
1002 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
1003 void *data ATTRIBUTE_UNUSED)
1005 *walk_subtrees = 0;
1006 return 0;
1009 /* Dummy function for code callback, for use when we really
1010 don't want to do anything. */
1012 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
1013 int *walk_subtrees ATTRIBUTE_UNUSED,
1014 void *data ATTRIBUTE_UNUSED)
1016 return 0;
1019 /* Code callback function for converting
1020 do while(a)
1021 end do
1022 into the equivalent
1024 if (.not. a) exit
1025 end do
1026 This is because common function elimination would otherwise place the
1027 temporary variables outside the loop. */
1029 static int
1030 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1031 void *data ATTRIBUTE_UNUSED)
1033 gfc_code *co = *c;
1034 gfc_code *c_if1, *c_if2, *c_exit;
1035 gfc_code *loopblock;
1036 gfc_expr *e_not, *e_cond;
1038 if (co->op != EXEC_DO_WHILE)
1039 return 0;
1041 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
1042 return 0;
1044 e_cond = co->expr1;
1046 /* Generate the condition of the if statement, which is .not. the original
1047 statement. */
1048 e_not = gfc_get_expr ();
1049 e_not->ts = e_cond->ts;
1050 e_not->where = e_cond->where;
1051 e_not->expr_type = EXPR_OP;
1052 e_not->value.op.op = INTRINSIC_NOT;
1053 e_not->value.op.op1 = e_cond;
1055 /* Generate the EXIT statement. */
1056 c_exit = XCNEW (gfc_code);
1057 c_exit->op = EXEC_EXIT;
1058 c_exit->ext.which_construct = co;
1059 c_exit->loc = co->loc;
1061 /* Generate the IF statement. */
1062 c_if2 = XCNEW (gfc_code);
1063 c_if2->op = EXEC_IF;
1064 c_if2->expr1 = e_not;
1065 c_if2->next = c_exit;
1066 c_if2->loc = co->loc;
1068 /* ... plus the one to chain it to. */
1069 c_if1 = XCNEW (gfc_code);
1070 c_if1->op = EXEC_IF;
1071 c_if1->block = c_if2;
1072 c_if1->loc = co->loc;
1074 /* Make the DO WHILE loop into a DO block by replacing the condition
1075 with a true constant. */
1076 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
1078 /* Hang the generated if statement into the loop body. */
1080 loopblock = co->block->next;
1081 co->block->next = c_if1;
1082 c_if1->next = loopblock;
1084 return 0;
1087 /* Code callback function for converting
1088 if (a) then
1090 else if (b) then
1091 end if
1093 into
1094 if (a) then
1095 else
1096 if (b) then
1097 end if
1098 end if
1100 because otherwise common function elimination would place the BLOCKs
1101 into the wrong place. */
1103 static int
1104 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1105 void *data ATTRIBUTE_UNUSED)
1107 gfc_code *co = *c;
1108 gfc_code *c_if1, *c_if2, *else_stmt;
1110 if (co->op != EXEC_IF)
1111 return 0;
1113 /* This loop starts out with the first ELSE statement. */
1114 else_stmt = co->block->block;
1116 while (else_stmt != NULL)
1118 gfc_code *next_else;
1120 /* If there is no condition, we're done. */
1121 if (else_stmt->expr1 == NULL)
1122 break;
1124 next_else = else_stmt->block;
1126 /* Generate the new IF statement. */
1127 c_if2 = XCNEW (gfc_code);
1128 c_if2->op = EXEC_IF;
1129 c_if2->expr1 = else_stmt->expr1;
1130 c_if2->next = else_stmt->next;
1131 c_if2->loc = else_stmt->loc;
1132 c_if2->block = next_else;
1134 /* ... plus the one to chain it to. */
1135 c_if1 = XCNEW (gfc_code);
1136 c_if1->op = EXEC_IF;
1137 c_if1->block = c_if2;
1138 c_if1->loc = else_stmt->loc;
1140 /* Insert the new IF after the ELSE. */
1141 else_stmt->expr1 = NULL;
1142 else_stmt->next = c_if1;
1143 else_stmt->block = NULL;
1145 else_stmt = next_else;
1147 /* Don't walk subtrees. */
1148 return 0;
1151 /* Callback function to var_in_expr - return true if expr1 and
1152 expr2 are identical variables. */
1153 static int
1154 var_in_expr_callback (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
1155 void *data)
1157 gfc_expr *expr1 = (gfc_expr *) data;
1158 gfc_expr *expr2 = *e;
1160 if (expr2->expr_type != EXPR_VARIABLE)
1161 return 0;
1163 return expr1->symtree->n.sym == expr2->symtree->n.sym;
1166 /* Return true if expr1 is found in expr2. */
1168 static bool
1169 var_in_expr (gfc_expr *expr1, gfc_expr *expr2)
1171 gcc_assert (expr1->expr_type == EXPR_VARIABLE);
1173 return gfc_expr_walker (&expr2, var_in_expr_callback, (void *) expr1);
1176 struct do_stack
1178 struct do_stack *prev;
1179 gfc_iterator *iter;
1180 gfc_code *code;
1181 } *stack_top;
1183 /* Recursively traverse the block of a WRITE or READ statement, and maybe
1184 optimize by replacing do loops with their analog array slices. For
1185 example:
1187 write (*,*) (a(i), i=1,4)
1189 is replaced with
1191 write (*,*) a(1:4:1) . */
1193 static bool
1194 traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
1196 gfc_code *curr;
1197 gfc_expr *new_e, *expr, *start;
1198 gfc_ref *ref;
1199 struct do_stack ds_push;
1200 int i, future_rank = 0;
1201 gfc_iterator *iters[GFC_MAX_DIMENSIONS];
1202 gfc_expr *e;
1204 /* Find the first transfer/do statement. */
1205 for (curr = code; curr; curr = curr->next)
1207 if (curr->op == EXEC_DO || curr->op == EXEC_TRANSFER)
1208 break;
1211 /* Ensure it is the only transfer/do statement because cases like
1213 write (*,*) (a(i), b(i), i=1,4)
1215 cannot be optimized. */
1217 if (!curr || curr->next)
1218 return false;
1220 if (curr->op == EXEC_DO)
1222 if (curr->ext.iterator->var->ref)
1223 return false;
1224 ds_push.prev = stack_top;
1225 ds_push.iter = curr->ext.iterator;
1226 ds_push.code = curr;
1227 stack_top = &ds_push;
1228 if (traverse_io_block (curr->block->next, has_reached, prev))
1230 if (curr != stack_top->code && !*has_reached)
1232 curr->block->next = NULL;
1233 gfc_free_statements (curr);
1235 else
1236 *has_reached = true;
1237 return true;
1239 return false;
1242 gcc_assert (curr->op == EXEC_TRANSFER);
1244 e = curr->expr1;
1245 ref = e->ref;
1246 if (!ref || ref->type != REF_ARRAY || ref->u.ar.codimen != 0 || ref->next)
1247 return false;
1249 /* Find the iterators belonging to each variable and check conditions. */
1250 for (i = 0; i < ref->u.ar.dimen; i++)
1252 if (!ref->u.ar.start[i] || ref->u.ar.start[i]->ref
1253 || ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1254 return false;
1256 start = ref->u.ar.start[i];
1257 gfc_simplify_expr (start, 0);
1258 switch (start->expr_type)
1260 case EXPR_VARIABLE:
1262 /* write (*,*) (a(i), i=a%b,1) not handled yet. */
1263 if (start->ref)
1264 return false;
1266 /* Check for (a(k), i=1,4) or ((a(j, i), i=1,4), j=1,4). */
1267 if (!stack_top || !stack_top->iter
1268 || stack_top->iter->var->symtree != start->symtree)
1270 /* Check for (a(i,i), i=1,3). */
1271 int j;
1273 for (j=0; j<i; j++)
1274 if (iters[j] && iters[j]->var->symtree == start->symtree)
1275 return false;
1277 iters[i] = NULL;
1279 else
1281 iters[i] = stack_top->iter;
1282 stack_top = stack_top->prev;
1283 future_rank++;
1285 break;
1286 case EXPR_CONSTANT:
1287 iters[i] = NULL;
1288 break;
1289 case EXPR_OP:
1290 switch (start->value.op.op)
1292 case INTRINSIC_PLUS:
1293 case INTRINSIC_TIMES:
1294 if (start->value.op.op1->expr_type != EXPR_VARIABLE)
1295 std::swap (start->value.op.op1, start->value.op.op2);
1296 gcc_fallthrough ();
1297 case INTRINSIC_MINUS:
1298 if ((start->value.op.op1->expr_type!= EXPR_VARIABLE
1299 && start->value.op.op2->expr_type != EXPR_CONSTANT)
1300 || start->value.op.op1->ref)
1301 return false;
1302 if (!stack_top || !stack_top->iter
1303 || stack_top->iter->var->symtree
1304 != start->value.op.op1->symtree)
1305 return false;
1306 iters[i] = stack_top->iter;
1307 stack_top = stack_top->prev;
1308 break;
1309 default:
1310 return false;
1312 future_rank++;
1313 break;
1314 default:
1315 return false;
1319 /* Check for cases like ((a(i, j), i=1, j), j=1, 2). */
1320 for (int i = 1; i < ref->u.ar.dimen; i++)
1322 if (iters[i])
1324 gfc_expr *var = iters[i]->var;
1325 for (int j = i - 1; j < i; j++)
1327 if (iters[j]
1328 && (var_in_expr (var, iters[j]->start)
1329 || var_in_expr (var, iters[j]->end)
1330 || var_in_expr (var, iters[j]->step)))
1331 return false;
1336 /* Create new expr. */
1337 new_e = gfc_copy_expr (curr->expr1);
1338 new_e->expr_type = EXPR_VARIABLE;
1339 new_e->rank = future_rank;
1340 if (curr->expr1->shape)
1341 new_e->shape = gfc_get_shape (new_e->rank);
1343 /* Assign new starts, ends and strides if necessary. */
1344 for (i = 0; i < ref->u.ar.dimen; i++)
1346 if (!iters[i])
1347 continue;
1348 start = ref->u.ar.start[i];
1349 switch (start->expr_type)
1351 case EXPR_CONSTANT:
1352 gfc_internal_error ("bad expression");
1353 break;
1354 case EXPR_VARIABLE:
1355 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1356 new_e->ref->u.ar.type = AR_SECTION;
1357 gfc_free_expr (new_e->ref->u.ar.start[i]);
1358 new_e->ref->u.ar.start[i] = gfc_copy_expr (iters[i]->start);
1359 new_e->ref->u.ar.end[i] = gfc_copy_expr (iters[i]->end);
1360 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1361 break;
1362 case EXPR_OP:
1363 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1364 new_e->ref->u.ar.type = AR_SECTION;
1365 gfc_free_expr (new_e->ref->u.ar.start[i]);
1366 expr = gfc_copy_expr (start);
1367 expr->value.op.op1 = gfc_copy_expr (iters[i]->start);
1368 new_e->ref->u.ar.start[i] = expr;
1369 gfc_simplify_expr (new_e->ref->u.ar.start[i], 0);
1370 expr = gfc_copy_expr (start);
1371 expr->value.op.op1 = gfc_copy_expr (iters[i]->end);
1372 new_e->ref->u.ar.end[i] = expr;
1373 gfc_simplify_expr (new_e->ref->u.ar.end[i], 0);
1374 switch (start->value.op.op)
1376 case INTRINSIC_MINUS:
1377 case INTRINSIC_PLUS:
1378 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1379 break;
1380 case INTRINSIC_TIMES:
1381 expr = gfc_copy_expr (start);
1382 expr->value.op.op1 = gfc_copy_expr (iters[i]->step);
1383 new_e->ref->u.ar.stride[i] = expr;
1384 gfc_simplify_expr (new_e->ref->u.ar.stride[i], 0);
1385 break;
1386 default:
1387 gfc_internal_error ("bad op");
1389 break;
1390 default:
1391 gfc_internal_error ("bad expression");
1394 curr->expr1 = new_e;
1396 /* Insert modified statement. Check whether the statement needs to be
1397 inserted at the lowest level. */
1398 if (!stack_top->iter)
1400 if (prev)
1402 curr->next = prev->next->next;
1403 prev->next = curr;
1405 else
1407 curr->next = stack_top->code->block->next->next->next;
1408 stack_top->code->block->next = curr;
1411 else
1412 stack_top->code->block->next = curr;
1413 return true;
1416 /* Function for the gfc_code_walker. If code is a READ or WRITE statement, it
1417 tries to optimize its block. */
1419 static int
1420 simplify_io_impl_do (gfc_code **code, int *walk_subtrees,
1421 void *data ATTRIBUTE_UNUSED)
1423 gfc_code **curr, *prev = NULL;
1424 struct do_stack write, first;
1425 bool b = false;
1426 *walk_subtrees = 1;
1427 if (!(*code)->block
1428 || ((*code)->block->op != EXEC_WRITE
1429 && (*code)->block->op != EXEC_READ))
1430 return 0;
1432 *walk_subtrees = 0;
1433 write.prev = NULL;
1434 write.iter = NULL;
1435 write.code = *code;
1437 for (curr = &(*code)->block; *curr; curr = &(*curr)->next)
1439 if ((*curr)->op == EXEC_DO)
1441 first.prev = &write;
1442 first.iter = (*curr)->ext.iterator;
1443 first.code = *curr;
1444 stack_top = &first;
1445 traverse_io_block ((*curr)->block->next, &b, prev);
1446 stack_top = NULL;
1448 prev = *curr;
1450 return 0;
1453 /* Optimize a namespace, including all contained namespaces.
1454 flag_frontend_optimize and flag_fronend_loop_interchange are
1455 handled separately. */
1457 static void
1458 optimize_namespace (gfc_namespace *ns)
1460 gfc_namespace *saved_ns = gfc_current_ns;
1461 current_ns = ns;
1462 gfc_current_ns = ns;
1463 forall_level = 0;
1464 iterator_level = 0;
1465 in_assoc_list = false;
1466 in_omp_workshare = false;
1468 if (flag_frontend_optimize)
1470 gfc_code_walker (&ns->code, simplify_io_impl_do, dummy_expr_callback, NULL);
1471 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
1472 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
1473 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
1474 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
1475 if (flag_inline_matmul_limit != 0 || flag_external_blas)
1477 bool found;
1480 found = false;
1481 gfc_code_walker (&ns->code, matmul_to_var_code, matmul_to_var_expr,
1482 (void *) &found);
1484 while (found);
1486 gfc_code_walker (&ns->code, matmul_temp_args, dummy_expr_callback,
1487 NULL);
1490 if (flag_external_blas)
1491 gfc_code_walker (&ns->code, call_external_blas, dummy_expr_callback,
1492 NULL);
1494 if (flag_inline_matmul_limit != 0)
1495 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
1496 NULL);
1499 if (flag_frontend_loop_interchange)
1500 gfc_code_walker (&ns->code, index_interchange, dummy_expr_callback,
1501 NULL);
1503 /* BLOCKs are handled in the expression walker below. */
1504 for (ns = ns->contained; ns; ns = ns->sibling)
1506 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1507 optimize_namespace (ns);
1509 gfc_current_ns = saved_ns;
1512 /* Handle dependencies for allocatable strings which potentially redefine
1513 themselves in an assignment. */
1515 static void
1516 realloc_strings (gfc_namespace *ns)
1518 current_ns = ns;
1519 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1521 for (ns = ns->contained; ns; ns = ns->sibling)
1523 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1524 realloc_strings (ns);
1529 static void
1530 optimize_reduction (gfc_namespace *ns)
1532 current_ns = ns;
1533 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1534 callback_reduction, NULL);
1536 /* BLOCKs are handled in the expression walker below. */
1537 for (ns = ns->contained; ns; ns = ns->sibling)
1539 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1540 optimize_reduction (ns);
1544 /* Replace code like
1545 a = matmul(b,c) + d
1546 with
1547 a = matmul(b,c) ; a = a + d
1548 where the array function is not elemental and not allocatable
1549 and does not depend on the left-hand side.
1552 static bool
1553 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1555 gfc_expr *e;
1557 if (!*rhs)
1558 return false;
1560 e = *rhs;
1561 if (e->expr_type == EXPR_OP)
1563 switch (e->value.op.op)
1565 /* Unary operators and exponentiation: Only look at a single
1566 operand. */
1567 case INTRINSIC_NOT:
1568 case INTRINSIC_UPLUS:
1569 case INTRINSIC_UMINUS:
1570 case INTRINSIC_PARENTHESES:
1571 case INTRINSIC_POWER:
1572 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
1573 return true;
1574 break;
1576 case INTRINSIC_CONCAT:
1577 /* Do not do string concatenations. */
1578 break;
1580 default:
1581 /* Binary operators. */
1582 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1583 return true;
1585 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1586 return true;
1588 break;
1591 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
1592 && ! (e->value.function.esym
1593 && (e->value.function.esym->attr.elemental
1594 || e->value.function.esym->attr.allocatable
1595 || e->value.function.esym->ts.type != c->expr1->ts.type
1596 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
1597 && ! (e->value.function.isym
1598 && (e->value.function.isym->elemental
1599 || e->ts.type != c->expr1->ts.type
1600 || e->ts.kind != c->expr1->ts.kind))
1601 && ! gfc_inline_intrinsic_function_p (e))
1604 gfc_code *n;
1605 gfc_expr *new_expr;
1607 /* Insert a new assignment statement after the current one. */
1608 n = XCNEW (gfc_code);
1609 n->op = EXEC_ASSIGN;
1610 n->loc = c->loc;
1611 n->next = c->next;
1612 c->next = n;
1614 n->expr1 = gfc_copy_expr (c->expr1);
1615 n->expr2 = c->expr2;
1616 new_expr = gfc_copy_expr (c->expr1);
1617 c->expr2 = e;
1618 *rhs = new_expr;
1620 return true;
1624 /* Nothing to optimize. */
1625 return false;
1628 /* Remove unneeded TRIMs at the end of expressions. */
1630 static bool
1631 remove_trim (gfc_expr *rhs)
1633 bool ret;
1635 ret = false;
1636 if (!rhs)
1637 return ret;
1639 /* Check for a // b // trim(c). Looping is probably not
1640 necessary because the parser usually generates
1641 (// (// a b ) trim(c) ) , but better safe than sorry. */
1643 while (rhs->expr_type == EXPR_OP
1644 && rhs->value.op.op == INTRINSIC_CONCAT)
1645 rhs = rhs->value.op.op2;
1647 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1648 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1650 strip_function_call (rhs);
1651 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1652 remove_trim (rhs);
1653 ret = true;
1656 return ret;
1659 /* Optimizations for an assignment. */
1661 static void
1662 optimize_assignment (gfc_code * c)
1664 gfc_expr *lhs, *rhs;
1666 lhs = c->expr1;
1667 rhs = c->expr2;
1669 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1671 /* Optimize a = trim(b) to a = b. */
1672 remove_trim (rhs);
1674 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1675 if (is_empty_string (rhs))
1676 rhs->value.character.length = 0;
1679 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1680 optimize_binop_array_assignment (c, &rhs, false);
1684 /* Remove an unneeded function call, modifying the expression.
1685 This replaces the function call with the value of its
1686 first argument. The rest of the argument list is freed. */
1688 static void
1689 strip_function_call (gfc_expr *e)
1691 gfc_expr *e1;
1692 gfc_actual_arglist *a;
1694 a = e->value.function.actual;
1696 /* We should have at least one argument. */
1697 gcc_assert (a->expr != NULL);
1699 e1 = a->expr;
1701 /* Free the remaining arglist, if any. */
1702 if (a->next)
1703 gfc_free_actual_arglist (a->next);
1705 /* Graft the argument expression onto the original function. */
1706 *e = *e1;
1707 free (e1);
1711 /* Optimization of lexical comparison functions. */
1713 static bool
1714 optimize_lexical_comparison (gfc_expr *e)
1716 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1717 return false;
1719 switch (e->value.function.isym->id)
1721 case GFC_ISYM_LLE:
1722 return optimize_comparison (e, INTRINSIC_LE);
1724 case GFC_ISYM_LGE:
1725 return optimize_comparison (e, INTRINSIC_GE);
1727 case GFC_ISYM_LGT:
1728 return optimize_comparison (e, INTRINSIC_GT);
1730 case GFC_ISYM_LLT:
1731 return optimize_comparison (e, INTRINSIC_LT);
1733 default:
1734 break;
1736 return false;
1739 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1740 do CHARACTER because of possible pessimization involving character
1741 lengths. */
1743 static bool
1744 combine_array_constructor (gfc_expr *e)
1747 gfc_expr *op1, *op2;
1748 gfc_expr *scalar;
1749 gfc_expr *new_expr;
1750 gfc_constructor *c, *new_c;
1751 gfc_constructor_base oldbase, newbase;
1752 bool scalar_first;
1753 int n_elem;
1754 bool all_const;
1756 /* Array constructors have rank one. */
1757 if (e->rank != 1)
1758 return false;
1760 /* Don't try to combine association lists, this makes no sense
1761 and leads to an ICE. */
1762 if (in_assoc_list)
1763 return false;
1765 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1766 if (forall_level > 0)
1767 return false;
1769 /* Inside an iterator, things can get hairy; we are likely to create
1770 an invalid temporary variable. */
1771 if (iterator_level > 0)
1772 return false;
1774 /* WHERE also doesn't work. */
1775 if (in_where > 0)
1776 return false;
1778 op1 = e->value.op.op1;
1779 op2 = e->value.op.op2;
1781 if (!op1 || !op2)
1782 return false;
1784 if (op1->expr_type == EXPR_ARRAY && op2->rank == 0)
1785 scalar_first = false;
1786 else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0)
1788 scalar_first = true;
1789 op1 = e->value.op.op2;
1790 op2 = e->value.op.op1;
1792 else
1793 return false;
1795 if (op2->ts.type == BT_CHARACTER)
1796 return false;
1798 /* This might be an expanded constructor with very many constant values. If
1799 we perform the operation here, we might end up with a long compile time
1800 and actually longer execution time, so a length bound is in order here.
1801 If the constructor constains something which is not a constant, it did
1802 not come from an expansion, so leave it alone. */
1804 #define CONSTR_LEN_MAX 4
1806 oldbase = op1->value.constructor;
1808 n_elem = 0;
1809 all_const = true;
1810 for (c = gfc_constructor_first (oldbase); c; c = gfc_constructor_next(c))
1812 if (c->expr->expr_type != EXPR_CONSTANT)
1814 all_const = false;
1815 break;
1817 n_elem += 1;
1820 if (all_const && n_elem > CONSTR_LEN_MAX)
1821 return false;
1823 #undef CONSTR_LEN_MAX
1825 newbase = NULL;
1826 e->expr_type = EXPR_ARRAY;
1828 scalar = create_var (gfc_copy_expr (op2), "constr");
1830 for (c = gfc_constructor_first (oldbase); c;
1831 c = gfc_constructor_next (c))
1833 new_expr = gfc_get_expr ();
1834 new_expr->ts = e->ts;
1835 new_expr->expr_type = EXPR_OP;
1836 new_expr->rank = c->expr->rank;
1837 new_expr->where = c->expr->where;
1838 new_expr->value.op.op = e->value.op.op;
1840 if (scalar_first)
1842 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1843 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1845 else
1847 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1848 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1851 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1852 new_c->iterator = c->iterator;
1853 c->iterator = NULL;
1856 gfc_free_expr (op1);
1857 gfc_free_expr (op2);
1858 gfc_free_expr (scalar);
1860 e->value.constructor = newbase;
1861 return true;
1864 /* Recursive optimization of operators. */
1866 static bool
1867 optimize_op (gfc_expr *e)
1869 bool changed;
1871 gfc_intrinsic_op op = e->value.op.op;
1873 changed = false;
1875 /* Only use new-style comparisons. */
1876 switch(op)
1878 case INTRINSIC_EQ_OS:
1879 op = INTRINSIC_EQ;
1880 break;
1882 case INTRINSIC_GE_OS:
1883 op = INTRINSIC_GE;
1884 break;
1886 case INTRINSIC_LE_OS:
1887 op = INTRINSIC_LE;
1888 break;
1890 case INTRINSIC_NE_OS:
1891 op = INTRINSIC_NE;
1892 break;
1894 case INTRINSIC_GT_OS:
1895 op = INTRINSIC_GT;
1896 break;
1898 case INTRINSIC_LT_OS:
1899 op = INTRINSIC_LT;
1900 break;
1902 default:
1903 break;
1906 switch (op)
1908 case INTRINSIC_EQ:
1909 case INTRINSIC_GE:
1910 case INTRINSIC_LE:
1911 case INTRINSIC_NE:
1912 case INTRINSIC_GT:
1913 case INTRINSIC_LT:
1914 changed = optimize_comparison (e, op);
1916 gcc_fallthrough ();
1917 /* Look at array constructors. */
1918 case INTRINSIC_PLUS:
1919 case INTRINSIC_MINUS:
1920 case INTRINSIC_TIMES:
1921 case INTRINSIC_DIVIDE:
1922 return combine_array_constructor (e) || changed;
1924 default:
1925 break;
1928 return false;
1932 /* Return true if a constant string contains only blanks. */
1934 static bool
1935 is_empty_string (gfc_expr *e)
1937 int i;
1939 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1940 return false;
1942 for (i=0; i < e->value.character.length; i++)
1944 if (e->value.character.string[i] != ' ')
1945 return false;
1948 return true;
1952 /* Insert a call to the intrinsic len_trim. Use a different name for
1953 the symbol tree so we don't run into trouble when the user has
1954 renamed len_trim for some reason. */
1956 static gfc_expr*
1957 get_len_trim_call (gfc_expr *str, int kind)
1959 gfc_expr *fcn;
1960 gfc_actual_arglist *actual_arglist, *next;
1962 fcn = gfc_get_expr ();
1963 fcn->expr_type = EXPR_FUNCTION;
1964 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1965 actual_arglist = gfc_get_actual_arglist ();
1966 actual_arglist->expr = str;
1967 next = gfc_get_actual_arglist ();
1968 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, kind);
1969 actual_arglist->next = next;
1971 fcn->value.function.actual = actual_arglist;
1972 fcn->where = str->where;
1973 fcn->ts.type = BT_INTEGER;
1974 fcn->ts.kind = gfc_charlen_int_kind;
1976 gfc_get_sym_tree ("__internal_len_trim", current_ns, &fcn->symtree, false);
1977 fcn->symtree->n.sym->ts = fcn->ts;
1978 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1979 fcn->symtree->n.sym->attr.function = 1;
1980 fcn->symtree->n.sym->attr.elemental = 1;
1981 fcn->symtree->n.sym->attr.referenced = 1;
1982 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
1983 gfc_commit_symbol (fcn->symtree->n.sym);
1985 return fcn;
1989 /* Optimize expressions for equality. */
1991 static bool
1992 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1994 gfc_expr *op1, *op2;
1995 bool change;
1996 int eq;
1997 bool result;
1998 gfc_actual_arglist *firstarg, *secondarg;
2000 if (e->expr_type == EXPR_OP)
2002 firstarg = NULL;
2003 secondarg = NULL;
2004 op1 = e->value.op.op1;
2005 op2 = e->value.op.op2;
2007 else if (e->expr_type == EXPR_FUNCTION)
2009 /* One of the lexical comparison functions. */
2010 firstarg = e->value.function.actual;
2011 secondarg = firstarg->next;
2012 op1 = firstarg->expr;
2013 op2 = secondarg->expr;
2015 else
2016 gcc_unreachable ();
2018 /* Strip off unneeded TRIM calls from string comparisons. */
2020 change = remove_trim (op1);
2022 if (remove_trim (op2))
2023 change = true;
2025 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
2026 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
2027 handles them well). However, there are also cases that need a non-scalar
2028 argument. For example the any intrinsic. See PR 45380. */
2029 if (e->rank > 0)
2030 return change;
2032 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
2033 len_trim(a) != 0 */
2034 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
2035 && (op == INTRINSIC_EQ || op == INTRINSIC_NE))
2037 bool empty_op1, empty_op2;
2038 empty_op1 = is_empty_string (op1);
2039 empty_op2 = is_empty_string (op2);
2041 if (empty_op1 || empty_op2)
2043 gfc_expr *fcn;
2044 gfc_expr *zero;
2045 gfc_expr *str;
2047 /* This can only happen when an error for comparing
2048 characters of different kinds has already been issued. */
2049 if (empty_op1 && empty_op2)
2050 return false;
2052 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
2053 str = empty_op1 ? op2 : op1;
2055 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
2058 if (empty_op1)
2059 gfc_free_expr (op1);
2060 else
2061 gfc_free_expr (op2);
2063 op1 = fcn;
2064 op2 = zero;
2065 e->value.op.op1 = fcn;
2066 e->value.op.op2 = zero;
2071 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
2073 if (flag_finite_math_only
2074 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
2075 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
2077 eq = gfc_dep_compare_expr (op1, op2);
2078 if (eq <= -2)
2080 /* Replace A // B < A // C with B < C, and A // B < C // B
2081 with A < C. */
2082 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
2083 && op1->expr_type == EXPR_OP
2084 && op1->value.op.op == INTRINSIC_CONCAT
2085 && op2->expr_type == EXPR_OP
2086 && op2->value.op.op == INTRINSIC_CONCAT)
2088 gfc_expr *op1_left = op1->value.op.op1;
2089 gfc_expr *op2_left = op2->value.op.op1;
2090 gfc_expr *op1_right = op1->value.op.op2;
2091 gfc_expr *op2_right = op2->value.op.op2;
2093 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
2095 /* Watch out for 'A ' // x vs. 'A' // x. */
2097 if (op1_left->expr_type == EXPR_CONSTANT
2098 && op2_left->expr_type == EXPR_CONSTANT
2099 && op1_left->value.character.length
2100 != op2_left->value.character.length)
2101 return change;
2102 else
2104 free (op1_left);
2105 free (op2_left);
2106 if (firstarg)
2108 firstarg->expr = op1_right;
2109 secondarg->expr = op2_right;
2111 else
2113 e->value.op.op1 = op1_right;
2114 e->value.op.op2 = op2_right;
2116 optimize_comparison (e, op);
2117 return true;
2120 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
2122 free (op1_right);
2123 free (op2_right);
2124 if (firstarg)
2126 firstarg->expr = op1_left;
2127 secondarg->expr = op2_left;
2129 else
2131 e->value.op.op1 = op1_left;
2132 e->value.op.op2 = op2_left;
2135 optimize_comparison (e, op);
2136 return true;
2140 else
2142 /* eq can only be -1, 0 or 1 at this point. */
2143 switch (op)
2145 case INTRINSIC_EQ:
2146 result = eq == 0;
2147 break;
2149 case INTRINSIC_GE:
2150 result = eq >= 0;
2151 break;
2153 case INTRINSIC_LE:
2154 result = eq <= 0;
2155 break;
2157 case INTRINSIC_NE:
2158 result = eq != 0;
2159 break;
2161 case INTRINSIC_GT:
2162 result = eq > 0;
2163 break;
2165 case INTRINSIC_LT:
2166 result = eq < 0;
2167 break;
2169 default:
2170 gfc_internal_error ("illegal OP in optimize_comparison");
2171 break;
2174 /* Replace the expression by a constant expression. The typespec
2175 and where remains the way it is. */
2176 free (op1);
2177 free (op2);
2178 e->expr_type = EXPR_CONSTANT;
2179 e->value.logical = result;
2180 return true;
2184 return change;
2187 /* Optimize a trim function by replacing it with an equivalent substring
2188 involving a call to len_trim. This only works for expressions where
2189 variables are trimmed. Return true if anything was modified. */
2191 static bool
2192 optimize_trim (gfc_expr *e)
2194 gfc_expr *a;
2195 gfc_ref *ref;
2196 gfc_expr *fcn;
2197 gfc_ref **rr = NULL;
2199 /* Don't do this optimization within an argument list, because
2200 otherwise aliasing issues may occur. */
2202 if (count_arglist != 1)
2203 return false;
2205 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
2206 || e->value.function.isym == NULL
2207 || e->value.function.isym->id != GFC_ISYM_TRIM)
2208 return false;
2210 a = e->value.function.actual->expr;
2212 if (a->expr_type != EXPR_VARIABLE)
2213 return false;
2215 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
2217 if (a->symtree->n.sym->attr.allocatable)
2218 return false;
2220 /* Follow all references to find the correct place to put the newly
2221 created reference. FIXME: Also handle substring references and
2222 array references. Array references cause strange regressions at
2223 the moment. */
2225 if (a->ref)
2227 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
2229 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
2230 return false;
2234 strip_function_call (e);
2236 if (e->ref == NULL)
2237 rr = &(e->ref);
2239 /* Create the reference. */
2241 ref = gfc_get_ref ();
2242 ref->type = REF_SUBSTRING;
2244 /* Set the start of the reference. */
2246 ref->u.ss.start = gfc_get_int_expr (gfc_charlen_int_kind, NULL, 1);
2248 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
2250 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_charlen_int_kind);
2252 /* Set the end of the reference to the call to len_trim. */
2254 ref->u.ss.end = fcn;
2255 gcc_assert (rr != NULL && *rr == NULL);
2256 *rr = ref;
2257 return true;
2260 /* Optimize minloc(b), where b is rank 1 array, into
2261 (/ minloc(b, dim=1) /), and similarly for maxloc,
2262 as the latter forms are expanded inline. */
2264 static void
2265 optimize_minmaxloc (gfc_expr **e)
2267 gfc_expr *fn = *e;
2268 gfc_actual_arglist *a;
2269 char *name, *p;
2271 if (fn->rank != 1
2272 || fn->value.function.actual == NULL
2273 || fn->value.function.actual->expr == NULL
2274 || fn->value.function.actual->expr->rank != 1)
2275 return;
2277 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
2278 (*e)->shape = fn->shape;
2279 fn->rank = 0;
2280 fn->shape = NULL;
2281 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
2283 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
2284 strcpy (name, fn->value.function.name);
2285 p = strstr (name, "loc0");
2286 p[3] = '1';
2287 fn->value.function.name = gfc_get_string ("%s", name);
2288 if (fn->value.function.actual->next)
2290 a = fn->value.function.actual->next;
2291 gcc_assert (a->expr == NULL);
2293 else
2295 a = gfc_get_actual_arglist ();
2296 fn->value.function.actual->next = a;
2298 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
2299 &fn->where);
2300 mpz_set_ui (a->expr->value.integer, 1);
2303 /* Callback function for code checking that we do not pass a DO variable to an
2304 INTENT(OUT) or INTENT(INOUT) dummy variable. */
2306 static int
2307 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2308 void *data ATTRIBUTE_UNUSED)
2310 gfc_code *co;
2311 int i;
2312 gfc_formal_arglist *f;
2313 gfc_actual_arglist *a;
2314 gfc_code *cl;
2315 do_t loop, *lp;
2316 bool seen_goto;
2318 co = *c;
2320 /* If the doloop_list grew, we have to truncate it here. */
2322 if ((unsigned) doloop_level < doloop_list.length())
2323 doloop_list.truncate (doloop_level);
2325 seen_goto = false;
2326 switch (co->op)
2328 case EXEC_DO:
2330 if (co->ext.iterator && co->ext.iterator->var)
2331 loop.c = co;
2332 else
2333 loop.c = NULL;
2335 loop.branch_level = if_level + select_level;
2336 loop.seen_goto = false;
2337 doloop_list.safe_push (loop);
2338 break;
2340 /* If anything could transfer control away from a suspicious
2341 subscript, make sure to set seen_goto in the current DO loop
2342 (if any). */
2343 case EXEC_GOTO:
2344 case EXEC_EXIT:
2345 case EXEC_STOP:
2346 case EXEC_ERROR_STOP:
2347 case EXEC_CYCLE:
2348 seen_goto = true;
2349 break;
2351 case EXEC_OPEN:
2352 if (co->ext.open->err)
2353 seen_goto = true;
2354 break;
2356 case EXEC_CLOSE:
2357 if (co->ext.close->err)
2358 seen_goto = true;
2359 break;
2361 case EXEC_BACKSPACE:
2362 case EXEC_ENDFILE:
2363 case EXEC_REWIND:
2364 case EXEC_FLUSH:
2366 if (co->ext.filepos->err)
2367 seen_goto = true;
2368 break;
2370 case EXEC_INQUIRE:
2371 if (co->ext.filepos->err)
2372 seen_goto = true;
2373 break;
2375 case EXEC_READ:
2376 case EXEC_WRITE:
2377 if (co->ext.dt->err || co->ext.dt->end || co->ext.dt->eor)
2378 seen_goto = true;
2379 break;
2381 case EXEC_WAIT:
2382 if (co->ext.wait->err || co->ext.wait->end || co->ext.wait->eor)
2383 loop.seen_goto = true;
2384 break;
2386 case EXEC_CALL:
2388 if (co->resolved_sym == NULL)
2389 break;
2391 f = gfc_sym_get_dummy_args (co->resolved_sym);
2393 /* Withot a formal arglist, there is only unknown INTENT,
2394 which we don't check for. */
2395 if (f == NULL)
2396 break;
2398 a = co->ext.actual;
2400 while (a && f)
2402 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2404 gfc_symbol *do_sym;
2405 cl = lp->c;
2407 if (cl == NULL)
2408 break;
2410 do_sym = cl->ext.iterator->var->symtree->n.sym;
2412 if (a->expr && a->expr->symtree
2413 && a->expr->symtree->n.sym == do_sym)
2415 if (f->sym->attr.intent == INTENT_OUT)
2416 gfc_error_now ("Variable %qs at %L set to undefined "
2417 "value inside loop beginning at %L as "
2418 "INTENT(OUT) argument to subroutine %qs",
2419 do_sym->name, &a->expr->where,
2420 &(doloop_list[i].c->loc),
2421 co->symtree->n.sym->name);
2422 else if (f->sym->attr.intent == INTENT_INOUT)
2423 gfc_error_now ("Variable %qs at %L not definable inside "
2424 "loop beginning at %L as INTENT(INOUT) "
2425 "argument to subroutine %qs",
2426 do_sym->name, &a->expr->where,
2427 &(doloop_list[i].c->loc),
2428 co->symtree->n.sym->name);
2431 a = a->next;
2432 f = f->next;
2434 break;
2436 default:
2437 break;
2439 if (seen_goto && doloop_level > 0)
2440 doloop_list[doloop_level-1].seen_goto = true;
2442 return 0;
2445 /* Callback function to warn about different things within DO loops. */
2447 static int
2448 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2449 void *data ATTRIBUTE_UNUSED)
2451 do_t *last;
2453 if (doloop_list.length () == 0)
2454 return 0;
2456 if ((*e)->expr_type == EXPR_FUNCTION)
2457 do_intent (e);
2459 last = &doloop_list.last();
2460 if (last->seen_goto && !warn_do_subscript)
2461 return 0;
2463 if ((*e)->expr_type == EXPR_VARIABLE)
2464 do_subscript (e);
2466 return 0;
2469 typedef struct
2471 gfc_symbol *sym;
2472 mpz_t val;
2473 } insert_index_t;
2475 /* Callback function - if the expression is the variable in data->sym,
2476 replace it with a constant from data->val. */
2478 static int
2479 callback_insert_index (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2480 void *data)
2482 insert_index_t *d;
2483 gfc_expr *ex, *n;
2485 ex = (*e);
2486 if (ex->expr_type != EXPR_VARIABLE)
2487 return 0;
2489 d = (insert_index_t *) data;
2490 if (ex->symtree->n.sym != d->sym)
2491 return 0;
2493 n = gfc_get_constant_expr (BT_INTEGER, ex->ts.kind, &ex->where);
2494 mpz_set (n->value.integer, d->val);
2496 gfc_free_expr (ex);
2497 *e = n;
2498 return 0;
2501 /* In the expression e, replace occurrences of the variable sym with
2502 val. If this results in a constant expression, return true and
2503 return the value in ret. Return false if the expression already
2504 is a constant. Caller has to clear ret in that case. */
2506 static bool
2507 insert_index (gfc_expr *e, gfc_symbol *sym, mpz_t val, mpz_t ret)
2509 gfc_expr *n;
2510 insert_index_t data;
2511 bool rc;
2513 if (e->expr_type == EXPR_CONSTANT)
2514 return false;
2516 n = gfc_copy_expr (e);
2517 data.sym = sym;
2518 mpz_init_set (data.val, val);
2519 gfc_expr_walker (&n, callback_insert_index, (void *) &data);
2521 /* Suppress errors here - we could get errors here such as an
2522 out of bounds access for arrays, see PR 90563. */
2523 gfc_push_suppress_errors ();
2524 gfc_simplify_expr (n, 0);
2525 gfc_pop_suppress_errors ();
2527 if (n->expr_type == EXPR_CONSTANT)
2529 rc = true;
2530 mpz_init_set (ret, n->value.integer);
2532 else
2533 rc = false;
2535 mpz_clear (data.val);
2536 gfc_free_expr (n);
2537 return rc;
2541 /* Check array subscripts for possible out-of-bounds accesses in DO
2542 loops with constant bounds. */
2544 static int
2545 do_subscript (gfc_expr **e)
2547 gfc_expr *v;
2548 gfc_array_ref *ar;
2549 gfc_ref *ref;
2550 int i,j;
2551 gfc_code *dl;
2552 do_t *lp;
2554 v = *e;
2555 /* Constants are already checked. */
2556 if (v->expr_type == EXPR_CONSTANT)
2557 return 0;
2559 /* Wrong warnings will be generated in an associate list. */
2560 if (in_assoc_list)
2561 return 0;
2563 /* We already warned about this. */
2564 if (v->do_not_warn)
2565 return 0;
2567 v->do_not_warn = 1;
2569 for (ref = v->ref; ref; ref = ref->next)
2571 if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT)
2573 ar = & ref->u.ar;
2574 FOR_EACH_VEC_ELT (doloop_list, j, lp)
2576 gfc_symbol *do_sym;
2577 mpz_t do_start, do_step, do_end;
2578 bool have_do_start, have_do_end;
2579 bool error_not_proven;
2580 int warn;
2582 dl = lp->c;
2583 if (dl == NULL)
2584 break;
2586 /* If we are within a branch, or a goto or equivalent
2587 was seen in the DO loop before, then we cannot prove that
2588 this expression is actually evaluated. Don't do anything
2589 unless we want to see it all. */
2590 error_not_proven = lp->seen_goto
2591 || lp->branch_level < if_level + select_level;
2593 if (error_not_proven && !warn_do_subscript)
2594 break;
2596 if (error_not_proven)
2597 warn = OPT_Wdo_subscript;
2598 else
2599 warn = 0;
2601 do_sym = dl->ext.iterator->var->symtree->n.sym;
2602 if (do_sym->ts.type != BT_INTEGER)
2603 continue;
2605 /* If we do not know about the stepsize, the loop may be zero trip.
2606 Do not warn in this case. */
2608 if (dl->ext.iterator->step->expr_type == EXPR_CONSTANT)
2609 mpz_init_set (do_step, dl->ext.iterator->step->value.integer);
2610 else
2611 continue;
2613 if (dl->ext.iterator->start->expr_type == EXPR_CONSTANT)
2615 have_do_start = true;
2616 mpz_init_set (do_start, dl->ext.iterator->start->value.integer);
2618 else
2619 have_do_start = false;
2621 if (dl->ext.iterator->end->expr_type == EXPR_CONSTANT)
2623 have_do_end = true;
2624 mpz_init_set (do_end, dl->ext.iterator->end->value.integer);
2626 else
2627 have_do_end = false;
2629 if (!have_do_start && !have_do_end)
2630 return 0;
2632 /* No warning inside a zero-trip loop. */
2633 if (have_do_start && have_do_end)
2635 int sgn, cmp;
2637 sgn = mpz_cmp_ui (do_step, 0);
2638 cmp = mpz_cmp (do_end, do_start);
2639 if ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0))
2640 break;
2643 /* May have to correct the end value if the step does not equal
2644 one. */
2645 if (have_do_start && have_do_end && mpz_cmp_ui (do_step, 1) != 0)
2647 mpz_t diff, rem;
2649 mpz_init (diff);
2650 mpz_init (rem);
2651 mpz_sub (diff, do_end, do_start);
2652 mpz_tdiv_r (rem, diff, do_step);
2653 mpz_sub (do_end, do_end, rem);
2654 mpz_clear (diff);
2655 mpz_clear (rem);
2658 for (i = 0; i< ar->dimen; i++)
2660 mpz_t val;
2661 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_start
2662 && insert_index (ar->start[i], do_sym, do_start, val))
2664 if (ar->as->lower[i]
2665 && ar->as->lower[i]->expr_type == EXPR_CONSTANT
2666 && mpz_cmp (val, ar->as->lower[i]->value.integer) < 0)
2667 gfc_warning (warn, "Array reference at %L out of bounds "
2668 "(%ld < %ld) in loop beginning at %L",
2669 &ar->start[i]->where, mpz_get_si (val),
2670 mpz_get_si (ar->as->lower[i]->value.integer),
2671 &doloop_list[j].c->loc);
2673 if (ar->as->upper[i]
2674 && ar->as->upper[i]->expr_type == EXPR_CONSTANT
2675 && mpz_cmp (val, ar->as->upper[i]->value.integer) > 0)
2676 gfc_warning (warn, "Array reference at %L out of bounds "
2677 "(%ld > %ld) in loop beginning at %L",
2678 &ar->start[i]->where, mpz_get_si (val),
2679 mpz_get_si (ar->as->upper[i]->value.integer),
2680 &doloop_list[j].c->loc);
2682 mpz_clear (val);
2685 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_end
2686 && insert_index (ar->start[i], do_sym, do_end, val))
2688 if (ar->as->lower[i]
2689 && ar->as->lower[i]->expr_type == EXPR_CONSTANT
2690 && mpz_cmp (val, ar->as->lower[i]->value.integer) < 0)
2691 gfc_warning (warn, "Array reference at %L out of bounds "
2692 "(%ld < %ld) in loop beginning at %L",
2693 &ar->start[i]->where, mpz_get_si (val),
2694 mpz_get_si (ar->as->lower[i]->value.integer),
2695 &doloop_list[j].c->loc);
2697 if (ar->as->upper[i]
2698 && ar->as->upper[i]->expr_type == EXPR_CONSTANT
2699 && mpz_cmp (val, ar->as->upper[i]->value.integer) > 0)
2700 gfc_warning (warn, "Array reference at %L out of bounds "
2701 "(%ld > %ld) in loop beginning at %L",
2702 &ar->start[i]->where, mpz_get_si (val),
2703 mpz_get_si (ar->as->upper[i]->value.integer),
2704 &doloop_list[j].c->loc);
2706 mpz_clear (val);
2712 return 0;
2714 /* Function for functions checking that we do not pass a DO variable
2715 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
2717 static int
2718 do_intent (gfc_expr **e)
2720 gfc_formal_arglist *f;
2721 gfc_actual_arglist *a;
2722 gfc_expr *expr;
2723 gfc_code *dl;
2724 do_t *lp;
2725 int i;
2727 expr = *e;
2728 if (expr->expr_type != EXPR_FUNCTION)
2729 return 0;
2731 /* Intrinsic functions don't modify their arguments. */
2733 if (expr->value.function.isym)
2734 return 0;
2736 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
2738 /* Without a formal arglist, there is only unknown INTENT,
2739 which we don't check for. */
2740 if (f == NULL)
2741 return 0;
2743 a = expr->value.function.actual;
2745 while (a && f)
2747 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2749 gfc_symbol *do_sym;
2750 dl = lp->c;
2751 if (dl == NULL)
2752 break;
2754 do_sym = dl->ext.iterator->var->symtree->n.sym;
2756 if (a->expr && a->expr->symtree
2757 && a->expr->symtree->n.sym == do_sym)
2759 if (f->sym->attr.intent == INTENT_OUT)
2760 gfc_error_now ("Variable %qs at %L set to undefined value "
2761 "inside loop beginning at %L as INTENT(OUT) "
2762 "argument to function %qs", do_sym->name,
2763 &a->expr->where, &doloop_list[i].c->loc,
2764 expr->symtree->n.sym->name);
2765 else if (f->sym->attr.intent == INTENT_INOUT)
2766 gfc_error_now ("Variable %qs at %L not definable inside loop"
2767 " beginning at %L as INTENT(INOUT) argument to"
2768 " function %qs", do_sym->name,
2769 &a->expr->where, &doloop_list[i].c->loc,
2770 expr->symtree->n.sym->name);
2773 a = a->next;
2774 f = f->next;
2777 return 0;
2780 static void
2781 doloop_warn (gfc_namespace *ns)
2783 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
2785 for (ns = ns->contained; ns; ns = ns->sibling)
2787 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
2788 doloop_warn (ns);
2792 /* This selction deals with inlining calls to MATMUL. */
2794 /* Replace calls to matmul outside of straight assignments with a temporary
2795 variable so that later inlining will work. */
2797 static int
2798 matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
2799 void *data)
2801 gfc_expr *e, *n;
2802 bool *found = (bool *) data;
2804 e = *ep;
2806 if (e->expr_type != EXPR_FUNCTION
2807 || e->value.function.isym == NULL
2808 || e->value.function.isym->id != GFC_ISYM_MATMUL)
2809 return 0;
2811 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2812 || in_where || in_assoc_list)
2813 return 0;
2815 /* Check if this is already in the form c = matmul(a,b). */
2817 if ((*current_code)->expr2 == e)
2818 return 0;
2820 n = create_var (e, "matmul");
2822 /* If create_var is unable to create a variable (for example if
2823 -fno-realloc-lhs is in force with a variable that does not have bounds
2824 known at compile-time), just return. */
2826 if (n == NULL)
2827 return 0;
2829 *ep = n;
2830 *found = true;
2831 return 0;
2834 /* Set current_code and associated variables so that matmul_to_var_expr can
2835 work. */
2837 static int
2838 matmul_to_var_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2839 void *data ATTRIBUTE_UNUSED)
2841 if (current_code != c)
2843 current_code = c;
2844 inserted_block = NULL;
2845 changed_statement = NULL;
2848 return 0;
2852 /* Take a statement of the shape c = matmul(a,b) and create temporaries
2853 for a and b if there is a dependency between the arguments and the
2854 result variable or if a or b are the result of calculations that cannot
2855 be handled by the inliner. */
2857 static int
2858 matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2859 void *data ATTRIBUTE_UNUSED)
2861 gfc_expr *expr1, *expr2;
2862 gfc_code *co;
2863 gfc_actual_arglist *a, *b;
2864 bool a_tmp, b_tmp;
2865 gfc_expr *matrix_a, *matrix_b;
2866 bool conjg_a, conjg_b, transpose_a, transpose_b;
2868 co = *c;
2870 if (co->op != EXEC_ASSIGN)
2871 return 0;
2873 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2874 || in_where)
2875 return 0;
2877 /* This has some duplication with inline_matmul_assign. This
2878 is because the creation of temporary variables could still fail,
2879 and inline_matmul_assign still needs to be able to handle these
2880 cases. */
2881 expr1 = co->expr1;
2882 expr2 = co->expr2;
2884 if (expr2->expr_type != EXPR_FUNCTION
2885 || expr2->value.function.isym == NULL
2886 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
2887 return 0;
2889 a_tmp = false;
2890 a = expr2->value.function.actual;
2891 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
2892 if (matrix_a != NULL)
2894 if (matrix_a->expr_type == EXPR_VARIABLE
2895 && (gfc_check_dependency (matrix_a, expr1, true)
2896 || gfc_has_dimen_vector_ref (matrix_a)))
2897 a_tmp = true;
2899 else
2900 a_tmp = true;
2902 b_tmp = false;
2903 b = a->next;
2904 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
2905 if (matrix_b != NULL)
2907 if (matrix_b->expr_type == EXPR_VARIABLE
2908 && (gfc_check_dependency (matrix_b, expr1, true)
2909 || gfc_has_dimen_vector_ref (matrix_b)))
2910 b_tmp = true;
2912 else
2913 b_tmp = true;
2915 if (!a_tmp && !b_tmp)
2916 return 0;
2918 current_code = c;
2919 inserted_block = NULL;
2920 changed_statement = NULL;
2921 if (a_tmp)
2923 gfc_expr *at;
2924 at = create_var (a->expr,"mma");
2925 if (at)
2926 a->expr = at;
2928 if (b_tmp)
2930 gfc_expr *bt;
2931 bt = create_var (b->expr,"mmb");
2932 if (bt)
2933 b->expr = bt;
2935 return 0;
2938 /* Auxiliary function to build and simplify an array inquiry function.
2939 dim is zero-based. */
2941 static gfc_expr *
2942 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim, int okind = 0)
2944 gfc_expr *fcn;
2945 gfc_expr *dim_arg, *kind;
2946 const char *name;
2947 gfc_expr *ec;
2949 switch (id)
2951 case GFC_ISYM_LBOUND:
2952 name = "_gfortran_lbound";
2953 break;
2955 case GFC_ISYM_UBOUND:
2956 name = "_gfortran_ubound";
2957 break;
2959 case GFC_ISYM_SIZE:
2960 name = "_gfortran_size";
2961 break;
2963 default:
2964 gcc_unreachable ();
2967 dim_arg = gfc_get_int_expr (gfc_default_integer_kind, &e->where, dim);
2968 if (okind != 0)
2969 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2970 okind);
2971 else
2972 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2973 gfc_index_integer_kind);
2975 ec = gfc_copy_expr (e);
2977 /* No bounds checking, this will be done before the loops if -fcheck=bounds
2978 is in effect. */
2979 ec->no_bounds_check = 1;
2980 fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3,
2981 ec, dim_arg, kind);
2982 gfc_simplify_expr (fcn, 0);
2983 fcn->no_bounds_check = 1;
2984 return fcn;
2987 /* Builds a logical expression. */
2989 static gfc_expr*
2990 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2992 gfc_typespec ts;
2993 gfc_expr *res;
2995 ts.type = BT_LOGICAL;
2996 ts.kind = gfc_default_logical_kind;
2997 res = gfc_get_expr ();
2998 res->where = e1->where;
2999 res->expr_type = EXPR_OP;
3000 res->value.op.op = op;
3001 res->value.op.op1 = e1;
3002 res->value.op.op2 = e2;
3003 res->ts = ts;
3005 return res;
3009 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
3010 compatible typespecs. */
3012 static gfc_expr *
3013 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
3015 gfc_expr *res;
3017 res = gfc_get_expr ();
3018 res->ts = e1->ts;
3019 res->where = e1->where;
3020 res->expr_type = EXPR_OP;
3021 res->value.op.op = op;
3022 res->value.op.op1 = e1;
3023 res->value.op.op2 = e2;
3024 gfc_simplify_expr (res, 0);
3025 return res;
3028 /* Generate the IF statement for a runtime check if we want to do inlining or
3029 not - putting in the code for both branches and putting it into the syntax
3030 tree is the caller's responsibility. For fixed array sizes, this should be
3031 removed by DCE. Only called for rank-two matrices A and B. */
3033 static gfc_code *
3034 inline_limit_check (gfc_expr *a, gfc_expr *b, int limit)
3036 gfc_expr *inline_limit;
3037 gfc_code *if_1, *if_2, *else_2;
3038 gfc_expr *b2, *a2, *a1, *m1, *m2;
3039 gfc_typespec ts;
3040 gfc_expr *cond;
3042 /* Calculation is done in real to avoid integer overflow. */
3044 inline_limit = gfc_get_constant_expr (BT_REAL, gfc_default_real_kind,
3045 &a->where);
3046 mpfr_set_si (inline_limit->value.real, limit, GFC_RND_MODE);
3047 mpfr_pow_ui (inline_limit->value.real, inline_limit->value.real, 3,
3048 GFC_RND_MODE);
3050 a1 = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3051 a2 = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
3052 b2 = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3054 gfc_clear_ts (&ts);
3055 ts.type = BT_REAL;
3056 ts.kind = gfc_default_real_kind;
3057 gfc_convert_type_warn (a1, &ts, 2, 0);
3058 gfc_convert_type_warn (a2, &ts, 2, 0);
3059 gfc_convert_type_warn (b2, &ts, 2, 0);
3061 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
3062 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
3064 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
3065 gfc_simplify_expr (cond, 0);
3067 else_2 = XCNEW (gfc_code);
3068 else_2->op = EXEC_IF;
3069 else_2->loc = a->where;
3071 if_2 = XCNEW (gfc_code);
3072 if_2->op = EXEC_IF;
3073 if_2->expr1 = cond;
3074 if_2->loc = a->where;
3075 if_2->block = else_2;
3077 if_1 = XCNEW (gfc_code);
3078 if_1->op = EXEC_IF;
3079 if_1->block = if_2;
3080 if_1->loc = a->where;
3082 return if_1;
3086 /* Insert code to issue a runtime error if the expressions are not equal. */
3088 static gfc_code *
3089 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
3091 gfc_expr *cond;
3092 gfc_code *if_1, *if_2;
3093 gfc_code *c;
3094 gfc_actual_arglist *a1, *a2, *a3;
3096 gcc_assert (e1->where.lb);
3097 /* Build the call to runtime_error. */
3098 c = XCNEW (gfc_code);
3099 c->op = EXEC_CALL;
3100 c->loc = e1->where;
3102 /* Get a null-terminated message string. */
3104 a1 = gfc_get_actual_arglist ();
3105 a1->expr = gfc_get_character_expr (gfc_default_character_kind, &e1->where,
3106 msg, strlen(msg)+1);
3107 c->ext.actual = a1;
3109 /* Pass the value of the first expression. */
3110 a2 = gfc_get_actual_arglist ();
3111 a2->expr = gfc_copy_expr (e1);
3112 a1->next = a2;
3114 /* Pass the value of the second expression. */
3115 a3 = gfc_get_actual_arglist ();
3116 a3->expr = gfc_copy_expr (e2);
3117 a2->next = a3;
3119 gfc_check_fe_runtime_error (c->ext.actual);
3120 gfc_resolve_fe_runtime_error (c);
3122 if_2 = XCNEW (gfc_code);
3123 if_2->op = EXEC_IF;
3124 if_2->loc = e1->where;
3125 if_2->next = c;
3127 if_1 = XCNEW (gfc_code);
3128 if_1->op = EXEC_IF;
3129 if_1->block = if_2;
3130 if_1->loc = e1->where;
3132 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
3133 gfc_simplify_expr (cond, 0);
3134 if_2->expr1 = cond;
3136 return if_1;
3139 /* Handle matrix reallocation. Caller is responsible to insert into
3140 the code tree.
3142 For the two-dimensional case, build
3144 if (allocated(c)) then
3145 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
3146 deallocate(c)
3147 allocate (c(size(a,1), size(b,2)))
3148 end if
3149 else
3150 allocate (c(size(a,1),size(b,2)))
3151 end if
3153 and for the other cases correspondingly.
3156 static gfc_code *
3157 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
3158 enum matrix_case m_case)
3161 gfc_expr *allocated, *alloc_expr;
3162 gfc_code *if_alloc_1, *if_alloc_2, *if_size_1, *if_size_2;
3163 gfc_code *else_alloc;
3164 gfc_code *deallocate, *allocate1, *allocate_else;
3165 gfc_array_ref *ar;
3166 gfc_expr *cond, *ne1, *ne2;
3168 if (warn_realloc_lhs)
3169 gfc_warning (OPT_Wrealloc_lhs,
3170 "Code for reallocating the allocatable array at %L will "
3171 "be added", &c->where);
3173 alloc_expr = gfc_copy_expr (c);
3175 ar = gfc_find_array_ref (alloc_expr);
3176 gcc_assert (ar && ar->type == AR_FULL);
3178 /* c comes in as a full ref. Change it into a copy and make it into an
3179 element ref so it has the right form for for ALLOCATE. In the same
3180 switch statement, also generate the size comparison for the secod IF
3181 statement. */
3183 ar->type = AR_ELEMENT;
3185 switch (m_case)
3187 case A2B2:
3188 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3189 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3190 ne1 = build_logical_expr (INTRINSIC_NE,
3191 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3192 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
3193 ne2 = build_logical_expr (INTRINSIC_NE,
3194 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3195 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3196 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3197 break;
3199 case A2B2T:
3200 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3201 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
3203 ne1 = build_logical_expr (INTRINSIC_NE,
3204 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3205 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
3206 ne2 = build_logical_expr (INTRINSIC_NE,
3207 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3208 get_array_inq_function (GFC_ISYM_SIZE, b, 1));
3209 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3210 break;
3212 case A2TB2:
3214 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
3215 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3217 ne1 = build_logical_expr (INTRINSIC_NE,
3218 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3219 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3220 ne2 = build_logical_expr (INTRINSIC_NE,
3221 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3222 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3223 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3224 break;
3226 case A2B1:
3227 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3228 cond = build_logical_expr (INTRINSIC_NE,
3229 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3230 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3231 break;
3233 case A1B2:
3234 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3235 cond = build_logical_expr (INTRINSIC_NE,
3236 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3237 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3238 break;
3240 case A2TB2T:
3241 /* This can only happen for BLAS, we do not handle that case in
3242 inline mamtul. */
3243 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
3244 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
3246 ne1 = build_logical_expr (INTRINSIC_NE,
3247 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3248 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3249 ne2 = build_logical_expr (INTRINSIC_NE,
3250 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3251 get_array_inq_function (GFC_ISYM_SIZE, b, 1));
3253 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3254 break;
3256 default:
3257 gcc_unreachable();
3261 gfc_simplify_expr (cond, 0);
3263 /* We need two identical allocate statements in two
3264 branches of the IF statement. */
3266 allocate1 = XCNEW (gfc_code);
3267 allocate1->op = EXEC_ALLOCATE;
3268 allocate1->ext.alloc.list = gfc_get_alloc ();
3269 allocate1->loc = c->where;
3270 allocate1->ext.alloc.list->expr = gfc_copy_expr (alloc_expr);
3272 allocate_else = XCNEW (gfc_code);
3273 allocate_else->op = EXEC_ALLOCATE;
3274 allocate_else->ext.alloc.list = gfc_get_alloc ();
3275 allocate_else->loc = c->where;
3276 allocate_else->ext.alloc.list->expr = alloc_expr;
3278 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
3279 "_gfortran_allocated", c->where,
3280 1, gfc_copy_expr (c));
3282 deallocate = XCNEW (gfc_code);
3283 deallocate->op = EXEC_DEALLOCATE;
3284 deallocate->ext.alloc.list = gfc_get_alloc ();
3285 deallocate->ext.alloc.list->expr = gfc_copy_expr (c);
3286 deallocate->next = allocate1;
3287 deallocate->loc = c->where;
3289 if_size_2 = XCNEW (gfc_code);
3290 if_size_2->op = EXEC_IF;
3291 if_size_2->expr1 = cond;
3292 if_size_2->loc = c->where;
3293 if_size_2->next = deallocate;
3295 if_size_1 = XCNEW (gfc_code);
3296 if_size_1->op = EXEC_IF;
3297 if_size_1->block = if_size_2;
3298 if_size_1->loc = c->where;
3300 else_alloc = XCNEW (gfc_code);
3301 else_alloc->op = EXEC_IF;
3302 else_alloc->loc = c->where;
3303 else_alloc->next = allocate_else;
3305 if_alloc_2 = XCNEW (gfc_code);
3306 if_alloc_2->op = EXEC_IF;
3307 if_alloc_2->expr1 = allocated;
3308 if_alloc_2->loc = c->where;
3309 if_alloc_2->next = if_size_1;
3310 if_alloc_2->block = else_alloc;
3312 if_alloc_1 = XCNEW (gfc_code);
3313 if_alloc_1->op = EXEC_IF;
3314 if_alloc_1->block = if_alloc_2;
3315 if_alloc_1->loc = c->where;
3317 return if_alloc_1;
3320 /* Callback function for has_function_or_op. */
3322 static int
3323 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
3324 void *data ATTRIBUTE_UNUSED)
3326 if ((*e) == 0)
3327 return 0;
3328 else
3329 return (*e)->expr_type == EXPR_FUNCTION
3330 || (*e)->expr_type == EXPR_OP;
3333 /* Returns true if the expression contains a function. */
3335 static bool
3336 has_function_or_op (gfc_expr **e)
3338 if (e == NULL)
3339 return false;
3340 else
3341 return gfc_expr_walker (e, is_function_or_op, NULL);
3344 /* Freeze (assign to a temporary variable) a single expression. */
3346 static void
3347 freeze_expr (gfc_expr **ep)
3349 gfc_expr *ne;
3350 if (has_function_or_op (ep))
3352 ne = create_var (*ep, "freeze");
3353 *ep = ne;
3357 /* Go through an expression's references and assign them to temporary
3358 variables if they contain functions. This is usually done prior to
3359 front-end scalarization to avoid multiple invocations of functions. */
3361 static void
3362 freeze_references (gfc_expr *e)
3364 gfc_ref *r;
3365 gfc_array_ref *ar;
3366 int i;
3368 for (r=e->ref; r; r=r->next)
3370 if (r->type == REF_SUBSTRING)
3372 if (r->u.ss.start != NULL)
3373 freeze_expr (&r->u.ss.start);
3375 if (r->u.ss.end != NULL)
3376 freeze_expr (&r->u.ss.end);
3378 else if (r->type == REF_ARRAY)
3380 ar = &r->u.ar;
3381 switch (ar->type)
3383 case AR_FULL:
3384 break;
3386 case AR_SECTION:
3387 for (i=0; i<ar->dimen; i++)
3389 if (ar->dimen_type[i] == DIMEN_RANGE)
3391 freeze_expr (&ar->start[i]);
3392 freeze_expr (&ar->end[i]);
3393 freeze_expr (&ar->stride[i]);
3395 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
3397 freeze_expr (&ar->start[i]);
3400 break;
3402 case AR_ELEMENT:
3403 for (i=0; i<ar->dimen; i++)
3404 freeze_expr (&ar->start[i]);
3405 break;
3407 default:
3408 break;
3414 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
3416 static gfc_expr *
3417 convert_to_index_kind (gfc_expr *e)
3419 gfc_expr *res;
3421 gcc_assert (e != NULL);
3423 res = gfc_copy_expr (e);
3425 gcc_assert (e->ts.type == BT_INTEGER);
3427 if (res->ts.kind != gfc_index_integer_kind)
3429 gfc_typespec ts;
3430 gfc_clear_ts (&ts);
3431 ts.type = BT_INTEGER;
3432 ts.kind = gfc_index_integer_kind;
3434 gfc_convert_type_warn (e, &ts, 2, 0);
3437 return res;
3440 /* Function to create a DO loop including creation of the
3441 iteration variable. gfc_expr are copied.*/
3443 static gfc_code *
3444 create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where,
3445 gfc_namespace *ns, char *vname)
3448 char name[GFC_MAX_SYMBOL_LEN +1];
3449 gfc_symtree *symtree;
3450 gfc_symbol *symbol;
3451 gfc_expr *i;
3452 gfc_code *n, *n2;
3454 /* Create an expression for the iteration variable. */
3455 if (vname)
3456 sprintf (name, "__var_%d_do_%s", var_num++, vname);
3457 else
3458 sprintf (name, "__var_%d_do", var_num++);
3461 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
3462 gcc_unreachable ();
3464 /* Create the loop variable. */
3466 symbol = symtree->n.sym;
3467 symbol->ts.type = BT_INTEGER;
3468 symbol->ts.kind = gfc_index_integer_kind;
3469 symbol->attr.flavor = FL_VARIABLE;
3470 symbol->attr.referenced = 1;
3471 symbol->attr.dimension = 0;
3472 symbol->attr.fe_temp = 1;
3473 gfc_commit_symbol (symbol);
3475 i = gfc_get_expr ();
3476 i->expr_type = EXPR_VARIABLE;
3477 i->ts = symbol->ts;
3478 i->rank = 0;
3479 i->where = *where;
3480 i->symtree = symtree;
3482 /* ... and the nested DO statements. */
3483 n = XCNEW (gfc_code);
3484 n->op = EXEC_DO;
3485 n->loc = *where;
3486 n->ext.iterator = gfc_get_iterator ();
3487 n->ext.iterator->var = i;
3488 n->ext.iterator->start = convert_to_index_kind (start);
3489 n->ext.iterator->end = convert_to_index_kind (end);
3490 if (step)
3491 n->ext.iterator->step = convert_to_index_kind (step);
3492 else
3493 n->ext.iterator->step = gfc_get_int_expr (gfc_index_integer_kind,
3494 where, 1);
3496 n2 = XCNEW (gfc_code);
3497 n2->op = EXEC_DO;
3498 n2->loc = *where;
3499 n2->next = NULL;
3500 n->block = n2;
3501 return n;
3504 /* Get the upper bound of the DO loops for matmul along a dimension. This
3505 is one-based. */
3507 static gfc_expr*
3508 get_size_m1 (gfc_expr *e, int dimen)
3510 mpz_t size;
3511 gfc_expr *res;
3513 if (gfc_array_dimen_size (e, dimen - 1, &size))
3515 res = gfc_get_constant_expr (BT_INTEGER,
3516 gfc_index_integer_kind, &e->where);
3517 mpz_sub_ui (res->value.integer, size, 1);
3518 mpz_clear (size);
3520 else
3522 res = get_operand (INTRINSIC_MINUS,
3523 get_array_inq_function (GFC_ISYM_SIZE, e, dimen),
3524 gfc_get_int_expr (gfc_index_integer_kind,
3525 &e->where, 1));
3526 gfc_simplify_expr (res, 0);
3529 return res;
3532 /* Function to return a scalarized expression. It is assumed that indices are
3533 zero based to make generation of DO loops easier. A zero as index will
3534 access the first element along a dimension. Single element references will
3535 be skipped. A NULL as an expression will be replaced by a full reference.
3536 This assumes that the index loops have gfc_index_integer_kind, and that all
3537 references have been frozen. */
3539 static gfc_expr*
3540 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
3542 gfc_array_ref *ar;
3543 int i;
3544 int rank;
3545 gfc_expr *e;
3546 int i_index;
3547 bool was_fullref;
3549 e = gfc_copy_expr(e_in);
3551 rank = e->rank;
3553 ar = gfc_find_array_ref (e);
3555 /* We scalarize count_index variables, reducing the rank by count_index. */
3557 e->rank = rank - count_index;
3559 was_fullref = ar->type == AR_FULL;
3561 if (e->rank == 0)
3562 ar->type = AR_ELEMENT;
3563 else
3564 ar->type = AR_SECTION;
3566 /* Loop over the indices. For each index, create the expression
3567 index * stride + lbound(e, dim). */
3569 i_index = 0;
3570 for (i=0; i < ar->dimen; i++)
3572 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
3574 if (index[i_index] != NULL)
3576 gfc_expr *lbound, *nindex;
3577 gfc_expr *loopvar;
3579 loopvar = gfc_copy_expr (index[i_index]);
3581 if (ar->stride[i])
3583 gfc_expr *tmp;
3585 tmp = gfc_copy_expr(ar->stride[i]);
3586 if (tmp->ts.kind != gfc_index_integer_kind)
3588 gfc_typespec ts;
3589 gfc_clear_ts (&ts);
3590 ts.type = BT_INTEGER;
3591 ts.kind = gfc_index_integer_kind;
3592 gfc_convert_type (tmp, &ts, 2);
3594 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
3596 else
3597 nindex = loopvar;
3599 /* Calculate the lower bound of the expression. */
3600 if (ar->start[i])
3602 lbound = gfc_copy_expr (ar->start[i]);
3603 if (lbound->ts.kind != gfc_index_integer_kind)
3605 gfc_typespec ts;
3606 gfc_clear_ts (&ts);
3607 ts.type = BT_INTEGER;
3608 ts.kind = gfc_index_integer_kind;
3609 gfc_convert_type (lbound, &ts, 2);
3613 else
3615 gfc_expr *lbound_e;
3616 gfc_ref *ref;
3618 lbound_e = gfc_copy_expr (e_in);
3620 for (ref = lbound_e->ref; ref; ref = ref->next)
3621 if (ref->type == REF_ARRAY
3622 && (ref->u.ar.type == AR_FULL
3623 || ref->u.ar.type == AR_SECTION))
3624 break;
3626 if (ref->next)
3628 gfc_free_ref_list (ref->next);
3629 ref->next = NULL;
3632 if (!was_fullref)
3634 /* Look at full individual sections, like a(:). The first index
3635 is the lbound of a full ref. */
3636 int j;
3637 gfc_array_ref *ar;
3638 int to;
3640 ar = &ref->u.ar;
3642 /* For assumed size, we need to keep around the final
3643 reference in order not to get an error on resolution
3644 below, and we cannot use AR_FULL. */
3646 if (ar->as->type == AS_ASSUMED_SIZE)
3648 ar->type = AR_SECTION;
3649 to = ar->dimen - 1;
3651 else
3653 to = ar->dimen;
3654 ar->type = AR_FULL;
3657 for (j = 0; j < to; j++)
3659 gfc_free_expr (ar->start[j]);
3660 ar->start[j] = NULL;
3661 gfc_free_expr (ar->end[j]);
3662 ar->end[j] = NULL;
3663 gfc_free_expr (ar->stride[j]);
3664 ar->stride[j] = NULL;
3667 /* We have to get rid of the shape, if there is one. Do
3668 so by freeing it and calling gfc_resolve to rebuild
3669 it, if necessary. */
3671 if (lbound_e->shape)
3672 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
3674 lbound_e->rank = ar->dimen;
3675 gfc_resolve_expr (lbound_e);
3677 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
3678 i + 1);
3679 gfc_free_expr (lbound_e);
3682 ar->dimen_type[i] = DIMEN_ELEMENT;
3684 gfc_free_expr (ar->start[i]);
3685 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
3687 gfc_free_expr (ar->end[i]);
3688 ar->end[i] = NULL;
3689 gfc_free_expr (ar->stride[i]);
3690 ar->stride[i] = NULL;
3691 gfc_simplify_expr (ar->start[i], 0);
3693 else if (was_fullref)
3695 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
3697 i_index ++;
3701 /* Bounds checking will be done before the loops if -fcheck=bounds
3702 is in effect. */
3703 e->no_bounds_check = 1;
3704 return e;
3707 /* Helper function to check for a dimen vector as subscript. */
3709 bool
3710 gfc_has_dimen_vector_ref (gfc_expr *e)
3712 gfc_array_ref *ar;
3713 int i;
3715 ar = gfc_find_array_ref (e);
3716 gcc_assert (ar);
3717 if (ar->type == AR_FULL)
3718 return false;
3720 for (i=0; i<ar->dimen; i++)
3721 if (ar->dimen_type[i] == DIMEN_VECTOR)
3722 return true;
3724 return false;
3727 /* If handed an expression of the form
3729 TRANSPOSE(CONJG(A))
3731 check if A can be handled by matmul and return if there is an uneven number
3732 of CONJG calls. Return a pointer to the array when everything is OK, NULL
3733 otherwise. The caller has to check for the correct rank. */
3735 static gfc_expr*
3736 check_conjg_transpose_variable (gfc_expr *e, bool *conjg, bool *transpose)
3738 *conjg = false;
3739 *transpose = false;
3743 if (e->expr_type == EXPR_VARIABLE)
3745 gcc_assert (e->rank == 1 || e->rank == 2);
3746 return e;
3748 else if (e->expr_type == EXPR_FUNCTION)
3750 if (e->value.function.isym == NULL)
3751 return NULL;
3753 if (e->value.function.isym->id == GFC_ISYM_CONJG)
3754 *conjg = !*conjg;
3755 else if (e->value.function.isym->id == GFC_ISYM_TRANSPOSE)
3756 *transpose = !*transpose;
3757 else return NULL;
3759 else
3760 return NULL;
3762 e = e->value.function.actual->expr;
3764 while(1);
3766 return NULL;
3769 /* Macros for unified error messages. */
3771 #define B_ERROR_1 _("Incorrect extent in argument B in MATMUL intrinsic in " \
3772 "dimension 1: is %ld, should be %ld")
3774 #define C_ERROR_1 _("Array bound mismatch for dimension 1 of array " \
3775 "(%ld/%ld)")
3777 #define C_ERROR_2 _("Array bound mismatch for dimension 2 of array " \
3778 "(%ld/%ld)")
3781 /* Inline assignments of the form c = matmul(a,b).
3782 Handle only the cases currently where b and c are rank-two arrays.
3784 This basically translates the code to
3786 BLOCK
3787 integer i,j,k
3788 c = 0
3789 do j=0, size(b,2)-1
3790 do k=0, size(a, 2)-1
3791 do i=0, size(a, 1)-1
3792 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
3793 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
3794 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
3795 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
3796 end do
3797 end do
3798 end do
3799 END BLOCK
3803 static int
3804 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
3805 void *data ATTRIBUTE_UNUSED)
3807 gfc_code *co = *c;
3808 gfc_expr *expr1, *expr2;
3809 gfc_expr *matrix_a, *matrix_b;
3810 gfc_actual_arglist *a, *b;
3811 gfc_code *do_1, *do_2, *do_3, *assign_zero, *assign_matmul;
3812 gfc_expr *zero_e;
3813 gfc_expr *u1, *u2, *u3;
3814 gfc_expr *list[2];
3815 gfc_expr *ascalar, *bscalar, *cscalar;
3816 gfc_expr *mult;
3817 gfc_expr *var_1, *var_2, *var_3;
3818 gfc_expr *zero;
3819 gfc_namespace *ns;
3820 gfc_intrinsic_op op_times, op_plus;
3821 enum matrix_case m_case;
3822 int i;
3823 gfc_code *if_limit = NULL;
3824 gfc_code **next_code_point;
3825 bool conjg_a, conjg_b, transpose_a, transpose_b;
3826 bool realloc_c;
3828 if (co->op != EXEC_ASSIGN)
3829 return 0;
3831 if (in_where || in_assoc_list)
3832 return 0;
3834 /* The BLOCKS generated for the temporary variables and FORALL don't
3835 mix. */
3836 if (forall_level > 0)
3837 return 0;
3839 /* For now don't do anything in OpenMP workshare, it confuses
3840 its translation, which expects only the allowed statements in there.
3841 We should figure out how to parallelize this eventually. */
3842 if (in_omp_workshare)
3843 return 0;
3845 expr1 = co->expr1;
3846 expr2 = co->expr2;
3847 if (expr2->expr_type != EXPR_FUNCTION
3848 || expr2->value.function.isym == NULL
3849 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
3850 return 0;
3852 current_code = c;
3853 inserted_block = NULL;
3854 changed_statement = NULL;
3856 a = expr2->value.function.actual;
3857 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
3858 if (matrix_a == NULL)
3859 return 0;
3861 b = a->next;
3862 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
3863 if (matrix_b == NULL)
3864 return 0;
3866 if (gfc_has_dimen_vector_ref (expr1) || gfc_has_dimen_vector_ref (matrix_a)
3867 || gfc_has_dimen_vector_ref (matrix_b))
3868 return 0;
3870 /* We do not handle data dependencies yet. */
3871 if (gfc_check_dependency (expr1, matrix_a, true)
3872 || gfc_check_dependency (expr1, matrix_b, true))
3873 return 0;
3875 m_case = none;
3876 if (matrix_a->rank == 2)
3878 if (transpose_a)
3880 if (matrix_b->rank == 2 && !transpose_b)
3881 m_case = A2TB2;
3883 else
3885 if (matrix_b->rank == 1)
3886 m_case = A2B1;
3887 else /* matrix_b->rank == 2 */
3889 if (transpose_b)
3890 m_case = A2B2T;
3891 else
3892 m_case = A2B2;
3896 else /* matrix_a->rank == 1 */
3898 if (matrix_b->rank == 2)
3900 if (!transpose_b)
3901 m_case = A1B2;
3905 if (m_case == none)
3906 return 0;
3908 ns = insert_block ();
3910 /* Assign the type of the zero expression for initializing the resulting
3911 array, and the expression (+ and * for real, integer and complex;
3912 .and. and .or for logical. */
3914 switch(expr1->ts.type)
3916 case BT_INTEGER:
3917 zero_e = gfc_get_int_expr (expr1->ts.kind, &expr1->where, 0);
3918 op_times = INTRINSIC_TIMES;
3919 op_plus = INTRINSIC_PLUS;
3920 break;
3922 case BT_LOGICAL:
3923 op_times = INTRINSIC_AND;
3924 op_plus = INTRINSIC_OR;
3925 zero_e = gfc_get_logical_expr (expr1->ts.kind, &expr1->where,
3927 break;
3928 case BT_REAL:
3929 zero_e = gfc_get_constant_expr (BT_REAL, expr1->ts.kind,
3930 &expr1->where);
3931 mpfr_set_si (zero_e->value.real, 0, GFC_RND_MODE);
3932 op_times = INTRINSIC_TIMES;
3933 op_plus = INTRINSIC_PLUS;
3934 break;
3936 case BT_COMPLEX:
3937 zero_e = gfc_get_constant_expr (BT_COMPLEX, expr1->ts.kind,
3938 &expr1->where);
3939 mpc_set_si_si (zero_e->value.complex, 0, 0, GFC_RND_MODE);
3940 op_times = INTRINSIC_TIMES;
3941 op_plus = INTRINSIC_PLUS;
3943 break;
3945 default:
3946 gcc_unreachable();
3949 current_code = &ns->code;
3951 /* Freeze the references, keeping track of how many temporary variables were
3952 created. */
3953 n_vars = 0;
3954 freeze_references (matrix_a);
3955 freeze_references (matrix_b);
3956 freeze_references (expr1);
3958 if (n_vars == 0)
3959 next_code_point = current_code;
3960 else
3962 next_code_point = &ns->code;
3963 for (i=0; i<n_vars; i++)
3964 next_code_point = &(*next_code_point)->next;
3967 /* Take care of the inline flag. If the limit check evaluates to a
3968 constant, dead code elimination will eliminate the unneeded branch. */
3970 if (flag_inline_matmul_limit > 0 && matrix_a->rank == 2
3971 && matrix_b->rank == 2)
3973 if_limit = inline_limit_check (matrix_a, matrix_b,
3974 flag_inline_matmul_limit);
3976 /* Insert the original statement into the else branch. */
3977 if_limit->block->block->next = co;
3978 co->next = NULL;
3980 /* ... and the new ones go into the original one. */
3981 *next_code_point = if_limit;
3982 next_code_point = &if_limit->block->next;
3985 zero_e->no_bounds_check = 1;
3987 assign_zero = XCNEW (gfc_code);
3988 assign_zero->op = EXEC_ASSIGN;
3989 assign_zero->loc = co->loc;
3990 assign_zero->expr1 = gfc_copy_expr (expr1);
3991 assign_zero->expr1->no_bounds_check = 1;
3992 assign_zero->expr2 = zero_e;
3994 realloc_c = flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1);
3996 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3998 gfc_code *test;
3999 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
4001 switch (m_case)
4003 case A2B1:
4005 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4006 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4007 test = runtime_error_ne (b1, a2, B_ERROR_1);
4008 *next_code_point = test;
4009 next_code_point = &test->next;
4011 if (!realloc_c)
4013 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4014 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4015 test = runtime_error_ne (c1, a1, C_ERROR_1);
4016 *next_code_point = test;
4017 next_code_point = &test->next;
4019 break;
4021 case A1B2:
4023 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4024 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4025 test = runtime_error_ne (b1, a1, B_ERROR_1);
4026 *next_code_point = test;
4027 next_code_point = &test->next;
4029 if (!realloc_c)
4031 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4032 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4033 test = runtime_error_ne (c1, b2, C_ERROR_1);
4034 *next_code_point = test;
4035 next_code_point = &test->next;
4037 break;
4039 case A2B2:
4041 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4042 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4043 test = runtime_error_ne (b1, a2, B_ERROR_1);
4044 *next_code_point = test;
4045 next_code_point = &test->next;
4047 if (!realloc_c)
4049 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4050 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4051 test = runtime_error_ne (c1, a1, C_ERROR_1);
4052 *next_code_point = test;
4053 next_code_point = &test->next;
4055 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4056 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4057 test = runtime_error_ne (c2, b2, C_ERROR_2);
4058 *next_code_point = test;
4059 next_code_point = &test->next;
4061 break;
4063 case A2B2T:
4065 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4066 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4067 /* matrix_b is transposed, hence dimension 1 for the error message. */
4068 test = runtime_error_ne (b2, a2, B_ERROR_1);
4069 *next_code_point = test;
4070 next_code_point = &test->next;
4072 if (!realloc_c)
4074 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4075 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4076 test = runtime_error_ne (c1, a1, C_ERROR_1);
4077 *next_code_point = test;
4078 next_code_point = &test->next;
4080 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4081 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4082 test = runtime_error_ne (c2, b1, C_ERROR_2);
4083 *next_code_point = test;
4084 next_code_point = &test->next;
4086 break;
4088 case A2TB2:
4090 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4091 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4092 test = runtime_error_ne (b1, a1, B_ERROR_1);
4093 *next_code_point = test;
4094 next_code_point = &test->next;
4096 if (!realloc_c)
4098 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4099 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4100 test = runtime_error_ne (c1, a2, C_ERROR_1);
4101 *next_code_point = test;
4102 next_code_point = &test->next;
4104 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4105 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4106 test = runtime_error_ne (c2, b2, C_ERROR_2);
4107 *next_code_point = test;
4108 next_code_point = &test->next;
4110 break;
4112 default:
4113 gcc_unreachable ();
4117 /* Handle the reallocation, if needed. */
4119 if (realloc_c)
4121 gfc_code *lhs_alloc;
4123 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
4125 *next_code_point = lhs_alloc;
4126 next_code_point = &lhs_alloc->next;
4130 *next_code_point = assign_zero;
4132 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
4134 assign_matmul = XCNEW (gfc_code);
4135 assign_matmul->op = EXEC_ASSIGN;
4136 assign_matmul->loc = co->loc;
4138 /* Get the bounds for the loops, create them and create the scalarized
4139 expressions. */
4141 switch (m_case)
4143 case A2B2:
4145 u1 = get_size_m1 (matrix_b, 2);
4146 u2 = get_size_m1 (matrix_a, 2);
4147 u3 = 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);
4151 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4153 do_1->block->next = do_2;
4154 do_2->block->next = do_3;
4155 do_3->block->next = assign_matmul;
4157 var_1 = do_1->ext.iterator->var;
4158 var_2 = do_2->ext.iterator->var;
4159 var_3 = do_3->ext.iterator->var;
4161 list[0] = var_3;
4162 list[1] = var_1;
4163 cscalar = scalarized_expr (co->expr1, list, 2);
4165 list[0] = var_3;
4166 list[1] = var_2;
4167 ascalar = scalarized_expr (matrix_a, list, 2);
4169 list[0] = var_2;
4170 list[1] = var_1;
4171 bscalar = scalarized_expr (matrix_b, list, 2);
4173 break;
4175 case A2B2T:
4177 u1 = get_size_m1 (matrix_b, 1);
4178 u2 = get_size_m1 (matrix_a, 2);
4179 u3 = get_size_m1 (matrix_a, 1);
4181 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4182 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4183 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4185 do_1->block->next = do_2;
4186 do_2->block->next = do_3;
4187 do_3->block->next = assign_matmul;
4189 var_1 = do_1->ext.iterator->var;
4190 var_2 = do_2->ext.iterator->var;
4191 var_3 = do_3->ext.iterator->var;
4193 list[0] = var_3;
4194 list[1] = var_1;
4195 cscalar = scalarized_expr (co->expr1, list, 2);
4197 list[0] = var_3;
4198 list[1] = var_2;
4199 ascalar = scalarized_expr (matrix_a, list, 2);
4201 list[0] = var_1;
4202 list[1] = var_2;
4203 bscalar = scalarized_expr (matrix_b, list, 2);
4205 break;
4207 case A2TB2:
4209 u1 = get_size_m1 (matrix_a, 2);
4210 u2 = get_size_m1 (matrix_b, 2);
4211 u3 = get_size_m1 (matrix_a, 1);
4213 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4214 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4215 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4217 do_1->block->next = do_2;
4218 do_2->block->next = do_3;
4219 do_3->block->next = assign_matmul;
4221 var_1 = do_1->ext.iterator->var;
4222 var_2 = do_2->ext.iterator->var;
4223 var_3 = do_3->ext.iterator->var;
4225 list[0] = var_1;
4226 list[1] = var_2;
4227 cscalar = scalarized_expr (co->expr1, list, 2);
4229 list[0] = var_3;
4230 list[1] = var_1;
4231 ascalar = scalarized_expr (matrix_a, list, 2);
4233 list[0] = var_3;
4234 list[1] = var_2;
4235 bscalar = scalarized_expr (matrix_b, list, 2);
4237 break;
4239 case A2B1:
4240 u1 = get_size_m1 (matrix_b, 1);
4241 u2 = get_size_m1 (matrix_a, 1);
4243 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4244 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4246 do_1->block->next = do_2;
4247 do_2->block->next = assign_matmul;
4249 var_1 = do_1->ext.iterator->var;
4250 var_2 = do_2->ext.iterator->var;
4252 list[0] = var_2;
4253 cscalar = scalarized_expr (co->expr1, list, 1);
4255 list[0] = var_2;
4256 list[1] = var_1;
4257 ascalar = scalarized_expr (matrix_a, list, 2);
4259 list[0] = var_1;
4260 bscalar = scalarized_expr (matrix_b, list, 1);
4262 break;
4264 case A1B2:
4265 u1 = get_size_m1 (matrix_b, 2);
4266 u2 = get_size_m1 (matrix_a, 1);
4268 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4269 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4271 do_1->block->next = do_2;
4272 do_2->block->next = assign_matmul;
4274 var_1 = do_1->ext.iterator->var;
4275 var_2 = do_2->ext.iterator->var;
4277 list[0] = var_1;
4278 cscalar = scalarized_expr (co->expr1, list, 1);
4280 list[0] = var_2;
4281 ascalar = scalarized_expr (matrix_a, list, 1);
4283 list[0] = var_2;
4284 list[1] = var_1;
4285 bscalar = scalarized_expr (matrix_b, list, 2);
4287 break;
4289 default:
4290 gcc_unreachable();
4293 /* Build the conjg call around the variables. Set the typespec manually
4294 because gfc_build_intrinsic_call sometimes gets this wrong. */
4295 if (conjg_a)
4297 gfc_typespec ts;
4298 ts = matrix_a->ts;
4299 ascalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
4300 matrix_a->where, 1, ascalar);
4301 ascalar->ts = ts;
4304 if (conjg_b)
4306 gfc_typespec ts;
4307 ts = matrix_b->ts;
4308 bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
4309 matrix_b->where, 1, bscalar);
4310 bscalar->ts = ts;
4312 /* First loop comes after the zero assignment. */
4313 assign_zero->next = do_1;
4315 /* Build the assignment expression in the loop. */
4316 assign_matmul->expr1 = gfc_copy_expr (cscalar);
4318 mult = get_operand (op_times, ascalar, bscalar);
4319 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
4321 /* If we don't want to keep the original statement around in
4322 the else branch, we can free it. */
4324 if (if_limit == NULL)
4325 gfc_free_statements(co);
4326 else
4327 co->next = NULL;
4329 gfc_free_expr (zero);
4330 *walk_subtrees = 0;
4331 return 0;
4334 /* Change matmul function calls in the form of
4336 c = matmul(a,b)
4338 to the corresponding call to a BLAS routine, if applicable. */
4340 static int
4341 call_external_blas (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
4342 void *data ATTRIBUTE_UNUSED)
4344 gfc_code *co, *co_next;
4345 gfc_expr *expr1, *expr2;
4346 gfc_expr *matrix_a, *matrix_b;
4347 gfc_code *if_limit = NULL;
4348 gfc_actual_arglist *a, *b;
4349 bool conjg_a, conjg_b, transpose_a, transpose_b;
4350 gfc_code *call;
4351 const char *blas_name;
4352 const char *transa, *transb;
4353 gfc_expr *c1, *c2, *b1;
4354 gfc_actual_arglist *actual, *next;
4355 bt type;
4356 int kind;
4357 enum matrix_case m_case;
4358 bool realloc_c;
4359 gfc_code **next_code_point;
4361 /* Many of the tests for inline matmul also apply here. */
4363 co = *c;
4365 if (co->op != EXEC_ASSIGN)
4366 return 0;
4368 if (in_where || in_assoc_list)
4369 return 0;
4371 /* The BLOCKS generated for the temporary variables and FORALL don't
4372 mix. */
4373 if (forall_level > 0)
4374 return 0;
4376 /* For now don't do anything in OpenMP workshare, it confuses
4377 its translation, which expects only the allowed statements in there. */
4379 if (in_omp_workshare)
4380 return 0;
4382 expr1 = co->expr1;
4383 expr2 = co->expr2;
4384 if (expr2->expr_type != EXPR_FUNCTION
4385 || expr2->value.function.isym == NULL
4386 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
4387 return 0;
4389 type = expr2->ts.type;
4390 kind = expr2->ts.kind;
4392 /* Guard against recursion. */
4394 if (expr2->external_blas)
4395 return 0;
4397 if (type != expr1->ts.type || kind != expr1->ts.kind)
4398 return 0;
4400 if (type == BT_REAL)
4402 if (kind == 4)
4403 blas_name = "sgemm";
4404 else if (kind == 8)
4405 blas_name = "dgemm";
4406 else
4407 return 0;
4409 else if (type == BT_COMPLEX)
4411 if (kind == 4)
4412 blas_name = "cgemm";
4413 else if (kind == 8)
4414 blas_name = "zgemm";
4415 else
4416 return 0;
4418 else
4419 return 0;
4421 a = expr2->value.function.actual;
4422 if (a->expr->rank != 2)
4423 return 0;
4425 b = a->next;
4426 if (b->expr->rank != 2)
4427 return 0;
4429 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
4430 if (matrix_a == NULL)
4431 return 0;
4433 if (transpose_a)
4435 if (conjg_a)
4436 transa = "C";
4437 else
4438 transa = "T";
4440 else
4441 transa = "N";
4443 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
4444 if (matrix_b == NULL)
4445 return 0;
4447 if (transpose_b)
4449 if (conjg_b)
4450 transb = "C";
4451 else
4452 transb = "T";
4454 else
4455 transb = "N";
4457 if (transpose_a)
4459 if (transpose_b)
4460 m_case = A2TB2T;
4461 else
4462 m_case = A2TB2;
4464 else
4466 if (transpose_b)
4467 m_case = A2B2T;
4468 else
4469 m_case = A2B2;
4472 current_code = c;
4473 inserted_block = NULL;
4474 changed_statement = NULL;
4476 expr2->external_blas = 1;
4478 /* We do not handle data dependencies yet. */
4479 if (gfc_check_dependency (expr1, matrix_a, true)
4480 || gfc_check_dependency (expr1, matrix_b, true))
4481 return 0;
4483 /* Generate the if statement and hang it into the tree. */
4484 if_limit = inline_limit_check (matrix_a, matrix_b, flag_blas_matmul_limit);
4485 co_next = co->next;
4486 (*current_code) = if_limit;
4487 co->next = NULL;
4488 if_limit->block->next = co;
4490 call = XCNEW (gfc_code);
4491 call->loc = co->loc;
4493 /* Bounds checking - a bit simpler than for inlining since we only
4494 have to take care of two-dimensional arrays here. */
4496 realloc_c = flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1);
4497 next_code_point = &(if_limit->block->block->next);
4499 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4501 gfc_code *test;
4502 // gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
4503 gfc_expr *c1, *a1, *c2, *b2, *a2;
4504 switch (m_case)
4506 case A2B2:
4507 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4508 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4509 test = runtime_error_ne (b1, a2, B_ERROR_1);
4510 *next_code_point = test;
4511 next_code_point = &test->next;
4513 if (!realloc_c)
4515 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4516 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4517 test = runtime_error_ne (c1, a1, C_ERROR_1);
4518 *next_code_point = test;
4519 next_code_point = &test->next;
4521 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4522 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4523 test = runtime_error_ne (c2, b2, C_ERROR_2);
4524 *next_code_point = test;
4525 next_code_point = &test->next;
4527 break;
4529 case A2B2T:
4531 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4532 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4533 /* matrix_b is transposed, hence dimension 1 for the error message. */
4534 test = runtime_error_ne (b2, a2, B_ERROR_1);
4535 *next_code_point = test;
4536 next_code_point = &test->next;
4538 if (!realloc_c)
4540 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4541 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4542 test = runtime_error_ne (c1, a1, C_ERROR_1);
4543 *next_code_point = test;
4544 next_code_point = &test->next;
4546 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4547 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4548 test = runtime_error_ne (c2, b1, C_ERROR_2);
4549 *next_code_point = test;
4550 next_code_point = &test->next;
4552 break;
4554 case A2TB2:
4556 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4557 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4558 test = runtime_error_ne (b1, a1, B_ERROR_1);
4559 *next_code_point = test;
4560 next_code_point = &test->next;
4562 if (!realloc_c)
4564 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4565 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4566 test = runtime_error_ne (c1, a2, C_ERROR_1);
4567 *next_code_point = test;
4568 next_code_point = &test->next;
4570 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4571 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4572 test = runtime_error_ne (c2, b2, C_ERROR_2);
4573 *next_code_point = test;
4574 next_code_point = &test->next;
4576 break;
4578 case A2TB2T:
4579 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4580 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4581 test = runtime_error_ne (b2, a1, B_ERROR_1);
4582 *next_code_point = test;
4583 next_code_point = &test->next;
4585 if (!realloc_c)
4587 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4588 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4589 test = runtime_error_ne (c1, a2, C_ERROR_1);
4590 *next_code_point = test;
4591 next_code_point = &test->next;
4593 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4594 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4595 test = runtime_error_ne (c2, b1, C_ERROR_2);
4596 *next_code_point = test;
4597 next_code_point = &test->next;
4599 break;
4601 default:
4602 gcc_unreachable ();
4606 /* Handle the reallocation, if needed. */
4608 if (realloc_c)
4610 gfc_code *lhs_alloc;
4612 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
4613 *next_code_point = lhs_alloc;
4614 next_code_point = &lhs_alloc->next;
4617 *next_code_point = call;
4618 if_limit->next = co_next;
4620 /* Set up the BLAS call. */
4622 call->op = EXEC_CALL;
4624 gfc_get_sym_tree (blas_name, current_ns, &(call->symtree), true);
4625 call->symtree->n.sym->attr.subroutine = 1;
4626 call->symtree->n.sym->attr.procedure = 1;
4627 call->symtree->n.sym->attr.flavor = FL_PROCEDURE;
4628 call->resolved_sym = call->symtree->n.sym;
4630 /* Argument TRANSA. */
4631 next = gfc_get_actual_arglist ();
4632 next->expr = gfc_get_character_expr (gfc_default_character_kind, &co->loc,
4633 transa, 1);
4635 call->ext.actual = next;
4637 /* Argument TRANSB. */
4638 actual = next;
4639 next = gfc_get_actual_arglist ();
4640 next->expr = gfc_get_character_expr (gfc_default_character_kind, &co->loc,
4641 transb, 1);
4642 actual->next = next;
4644 c1 = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (a->expr), 1,
4645 gfc_integer_4_kind);
4646 c2 = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (b->expr), 2,
4647 gfc_integer_4_kind);
4649 b1 = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (b->expr), 1,
4650 gfc_integer_4_kind);
4652 /* Argument M. */
4653 actual = next;
4654 next = gfc_get_actual_arglist ();
4655 next->expr = c1;
4656 actual->next = next;
4658 /* Argument N. */
4659 actual = next;
4660 next = gfc_get_actual_arglist ();
4661 next->expr = c2;
4662 actual->next = next;
4664 /* Argument K. */
4665 actual = next;
4666 next = gfc_get_actual_arglist ();
4667 next->expr = b1;
4668 actual->next = next;
4670 /* Argument ALPHA - set to one. */
4671 actual = next;
4672 next = gfc_get_actual_arglist ();
4673 next->expr = gfc_get_constant_expr (type, kind, &co->loc);
4674 if (type == BT_REAL)
4675 mpfr_set_ui (next->expr->value.real, 1, GFC_RND_MODE);
4676 else
4677 mpc_set_ui (next->expr->value.complex, 1, GFC_MPC_RND_MODE);
4678 actual->next = next;
4680 /* Argument A. */
4681 actual = next;
4682 next = gfc_get_actual_arglist ();
4683 next->expr = gfc_copy_expr (matrix_a);
4684 actual->next = next;
4686 /* Argument LDA. */
4687 actual = next;
4688 next = gfc_get_actual_arglist ();
4689 next->expr = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (matrix_a),
4690 1, gfc_integer_4_kind);
4691 actual->next = next;
4693 /* Argument B. */
4694 actual = next;
4695 next = gfc_get_actual_arglist ();
4696 next->expr = gfc_copy_expr (matrix_b);
4697 actual->next = next;
4699 /* Argument LDB. */
4700 actual = next;
4701 next = gfc_get_actual_arglist ();
4702 next->expr = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (matrix_b),
4703 1, gfc_integer_4_kind);
4704 actual->next = next;
4706 /* Argument BETA - set to zero. */
4707 actual = next;
4708 next = gfc_get_actual_arglist ();
4709 next->expr = gfc_get_constant_expr (type, kind, &co->loc);
4710 if (type == BT_REAL)
4711 mpfr_set_ui (next->expr->value.real, 0, GFC_RND_MODE);
4712 else
4713 mpc_set_ui (next->expr->value.complex, 0, GFC_MPC_RND_MODE);
4714 actual->next = next;
4716 /* Argument C. */
4718 actual = next;
4719 next = gfc_get_actual_arglist ();
4720 next->expr = gfc_copy_expr (expr1);
4721 actual->next = next;
4723 /* Argument LDC. */
4724 actual = next;
4725 next = gfc_get_actual_arglist ();
4726 next->expr = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (expr1),
4727 1, gfc_integer_4_kind);
4728 actual->next = next;
4730 return 0;
4734 /* Code for index interchange for loops which are grouped together in DO
4735 CONCURRENT or FORALL statements. This is currently only applied if the
4736 iterations are grouped together in a single statement.
4738 For this transformation, it is assumed that memory access in strides is
4739 expensive, and that loops which access later indices (which access memory
4740 in bigger strides) should be moved to the first loops.
4742 For this, a loop over all the statements is executed, counting the times
4743 that the loop iteration values are accessed in each index. The loop
4744 indices are then sorted to minimize access to later indices from inner
4745 loops. */
4747 /* Type for holding index information. */
4749 typedef struct {
4750 gfc_symbol *sym;
4751 gfc_forall_iterator *fa;
4752 int num;
4753 int n[GFC_MAX_DIMENSIONS];
4754 } ind_type;
4756 /* Callback function to determine if an expression is the
4757 corresponding variable. */
4759 static int
4760 has_var (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
4762 gfc_expr *expr = *e;
4763 gfc_symbol *sym;
4765 if (expr->expr_type != EXPR_VARIABLE)
4766 return 0;
4768 sym = (gfc_symbol *) data;
4769 return sym == expr->symtree->n.sym;
4772 /* Callback function to calculate the cost of a certain index. */
4774 static int
4775 index_cost (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
4776 void *data)
4778 ind_type *ind;
4779 gfc_expr *expr;
4780 gfc_array_ref *ar;
4781 gfc_ref *ref;
4782 int i,j;
4784 expr = *e;
4785 if (expr->expr_type != EXPR_VARIABLE)
4786 return 0;
4788 ar = NULL;
4789 for (ref = expr->ref; ref; ref = ref->next)
4791 if (ref->type == REF_ARRAY)
4793 ar = &ref->u.ar;
4794 break;
4797 if (ar == NULL || ar->type != AR_ELEMENT)
4798 return 0;
4800 ind = (ind_type *) data;
4801 for (i = 0; i < ar->dimen; i++)
4803 for (j=0; ind[j].sym != NULL; j++)
4805 if (gfc_expr_walker (&ar->start[i], has_var, (void *) (ind[j].sym)))
4806 ind[j].n[i]++;
4809 return 0;
4812 /* Callback function for qsort, to sort the loop indices. */
4814 static int
4815 loop_comp (const void *e1, const void *e2)
4817 const ind_type *i1 = (const ind_type *) e1;
4818 const ind_type *i2 = (const ind_type *) e2;
4819 int i;
4821 for (i=GFC_MAX_DIMENSIONS-1; i >= 0; i--)
4823 if (i1->n[i] != i2->n[i])
4824 return i1->n[i] - i2->n[i];
4826 /* All other things being equal, let's not change the ordering. */
4827 return i2->num - i1->num;
4830 /* Main function to do the index interchange. */
4832 static int
4833 index_interchange (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
4834 void *data ATTRIBUTE_UNUSED)
4836 gfc_code *co;
4837 co = *c;
4838 int n_iter;
4839 gfc_forall_iterator *fa;
4840 ind_type *ind;
4841 int i, j;
4843 if (co->op != EXEC_FORALL && co->op != EXEC_DO_CONCURRENT)
4844 return 0;
4846 n_iter = 0;
4847 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4848 n_iter ++;
4850 /* Nothing to reorder. */
4851 if (n_iter < 2)
4852 return 0;
4854 ind = XALLOCAVEC (ind_type, n_iter + 1);
4856 i = 0;
4857 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4859 ind[i].sym = fa->var->symtree->n.sym;
4860 ind[i].fa = fa;
4861 for (j=0; j<GFC_MAX_DIMENSIONS; j++)
4862 ind[i].n[j] = 0;
4863 ind[i].num = i;
4864 i++;
4866 ind[n_iter].sym = NULL;
4867 ind[n_iter].fa = NULL;
4869 gfc_code_walker (c, gfc_dummy_code_callback, index_cost, (void *) ind);
4870 qsort ((void *) ind, n_iter, sizeof (ind_type), loop_comp);
4872 /* Do the actual index interchange. */
4873 co->ext.forall_iterator = fa = ind[0].fa;
4874 for (i=1; i<n_iter; i++)
4876 fa->next = ind[i].fa;
4877 fa = fa->next;
4879 fa->next = NULL;
4881 if (flag_warn_frontend_loop_interchange)
4883 for (i=1; i<n_iter; i++)
4885 if (ind[i-1].num > ind[i].num)
4887 gfc_warning (OPT_Wfrontend_loop_interchange,
4888 "Interchanging loops at %L", &co->loc);
4889 break;
4894 return 0;
4897 #define WALK_SUBEXPR(NODE) \
4898 do \
4900 result = gfc_expr_walker (&(NODE), exprfn, data); \
4901 if (result) \
4902 return result; \
4904 while (0)
4905 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
4907 /* Walk expression *E, calling EXPRFN on each expression in it. */
4910 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
4912 while (*e)
4914 int walk_subtrees = 1;
4915 gfc_actual_arglist *a;
4916 gfc_ref *r;
4917 gfc_constructor *c;
4919 int result = exprfn (e, &walk_subtrees, data);
4920 if (result)
4921 return result;
4922 if (walk_subtrees)
4923 switch ((*e)->expr_type)
4925 case EXPR_OP:
4926 WALK_SUBEXPR ((*e)->value.op.op1);
4927 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
4928 break;
4929 case EXPR_FUNCTION:
4930 for (a = (*e)->value.function.actual; a; a = a->next)
4931 WALK_SUBEXPR (a->expr);
4932 break;
4933 case EXPR_COMPCALL:
4934 case EXPR_PPC:
4935 WALK_SUBEXPR ((*e)->value.compcall.base_object);
4936 for (a = (*e)->value.compcall.actual; a; a = a->next)
4937 WALK_SUBEXPR (a->expr);
4938 break;
4940 case EXPR_STRUCTURE:
4941 case EXPR_ARRAY:
4942 for (c = gfc_constructor_first ((*e)->value.constructor); c;
4943 c = gfc_constructor_next (c))
4945 if (c->iterator == NULL)
4946 WALK_SUBEXPR (c->expr);
4947 else
4949 iterator_level ++;
4950 WALK_SUBEXPR (c->expr);
4951 iterator_level --;
4952 WALK_SUBEXPR (c->iterator->var);
4953 WALK_SUBEXPR (c->iterator->start);
4954 WALK_SUBEXPR (c->iterator->end);
4955 WALK_SUBEXPR (c->iterator->step);
4959 if ((*e)->expr_type != EXPR_ARRAY)
4960 break;
4962 /* Fall through to the variable case in order to walk the
4963 reference. */
4964 gcc_fallthrough ();
4966 case EXPR_SUBSTRING:
4967 case EXPR_VARIABLE:
4968 for (r = (*e)->ref; r; r = r->next)
4970 gfc_array_ref *ar;
4971 int i;
4973 switch (r->type)
4975 case REF_ARRAY:
4976 ar = &r->u.ar;
4977 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
4979 for (i=0; i< ar->dimen; i++)
4981 WALK_SUBEXPR (ar->start[i]);
4982 WALK_SUBEXPR (ar->end[i]);
4983 WALK_SUBEXPR (ar->stride[i]);
4987 break;
4989 case REF_SUBSTRING:
4990 WALK_SUBEXPR (r->u.ss.start);
4991 WALK_SUBEXPR (r->u.ss.end);
4992 break;
4994 case REF_COMPONENT:
4995 case REF_INQUIRY:
4996 break;
5000 default:
5001 break;
5003 return 0;
5005 return 0;
5008 #define WALK_SUBCODE(NODE) \
5009 do \
5011 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
5012 if (result) \
5013 return result; \
5015 while (0)
5017 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
5018 on each expression in it. If any of the hooks returns non-zero, that
5019 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
5020 no subcodes or subexpressions are traversed. */
5023 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
5024 void *data)
5026 for (; *c; c = &(*c)->next)
5028 int walk_subtrees = 1;
5029 int result = codefn (c, &walk_subtrees, data);
5030 if (result)
5031 return result;
5033 if (walk_subtrees)
5035 gfc_code *b;
5036 gfc_actual_arglist *a;
5037 gfc_code *co;
5038 gfc_association_list *alist;
5039 bool saved_in_omp_workshare;
5040 bool saved_in_where;
5042 /* There might be statement insertions before the current code,
5043 which must not affect the expression walker. */
5045 co = *c;
5046 saved_in_omp_workshare = in_omp_workshare;
5047 saved_in_where = in_where;
5049 switch (co->op)
5052 case EXEC_BLOCK:
5053 WALK_SUBCODE (co->ext.block.ns->code);
5054 if (co->ext.block.assoc)
5056 bool saved_in_assoc_list = in_assoc_list;
5058 in_assoc_list = true;
5059 for (alist = co->ext.block.assoc; alist; alist = alist->next)
5060 WALK_SUBEXPR (alist->target);
5062 in_assoc_list = saved_in_assoc_list;
5065 break;
5067 case EXEC_DO:
5068 doloop_level ++;
5069 WALK_SUBEXPR (co->ext.iterator->var);
5070 WALK_SUBEXPR (co->ext.iterator->start);
5071 WALK_SUBEXPR (co->ext.iterator->end);
5072 WALK_SUBEXPR (co->ext.iterator->step);
5073 break;
5075 case EXEC_IF:
5076 if_level ++;
5077 break;
5079 case EXEC_WHERE:
5080 in_where = true;
5081 break;
5083 case EXEC_CALL:
5084 case EXEC_ASSIGN_CALL:
5085 for (a = co->ext.actual; a; a = a->next)
5086 WALK_SUBEXPR (a->expr);
5087 break;
5089 case EXEC_CALL_PPC:
5090 WALK_SUBEXPR (co->expr1);
5091 for (a = co->ext.actual; a; a = a->next)
5092 WALK_SUBEXPR (a->expr);
5093 break;
5095 case EXEC_SELECT:
5096 WALK_SUBEXPR (co->expr1);
5097 select_level ++;
5098 for (b = co->block; b; b = b->block)
5100 gfc_case *cp;
5101 for (cp = b->ext.block.case_list; cp; cp = cp->next)
5103 WALK_SUBEXPR (cp->low);
5104 WALK_SUBEXPR (cp->high);
5106 WALK_SUBCODE (b->next);
5108 continue;
5110 case EXEC_ALLOCATE:
5111 case EXEC_DEALLOCATE:
5113 gfc_alloc *a;
5114 for (a = co->ext.alloc.list; a; a = a->next)
5115 WALK_SUBEXPR (a->expr);
5116 break;
5119 case EXEC_FORALL:
5120 case EXEC_DO_CONCURRENT:
5122 gfc_forall_iterator *fa;
5123 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
5125 WALK_SUBEXPR (fa->var);
5126 WALK_SUBEXPR (fa->start);
5127 WALK_SUBEXPR (fa->end);
5128 WALK_SUBEXPR (fa->stride);
5130 if (co->op == EXEC_FORALL)
5131 forall_level ++;
5132 break;
5135 case EXEC_OPEN:
5136 WALK_SUBEXPR (co->ext.open->unit);
5137 WALK_SUBEXPR (co->ext.open->file);
5138 WALK_SUBEXPR (co->ext.open->status);
5139 WALK_SUBEXPR (co->ext.open->access);
5140 WALK_SUBEXPR (co->ext.open->form);
5141 WALK_SUBEXPR (co->ext.open->recl);
5142 WALK_SUBEXPR (co->ext.open->blank);
5143 WALK_SUBEXPR (co->ext.open->position);
5144 WALK_SUBEXPR (co->ext.open->action);
5145 WALK_SUBEXPR (co->ext.open->delim);
5146 WALK_SUBEXPR (co->ext.open->pad);
5147 WALK_SUBEXPR (co->ext.open->iostat);
5148 WALK_SUBEXPR (co->ext.open->iomsg);
5149 WALK_SUBEXPR (co->ext.open->convert);
5150 WALK_SUBEXPR (co->ext.open->decimal);
5151 WALK_SUBEXPR (co->ext.open->encoding);
5152 WALK_SUBEXPR (co->ext.open->round);
5153 WALK_SUBEXPR (co->ext.open->sign);
5154 WALK_SUBEXPR (co->ext.open->asynchronous);
5155 WALK_SUBEXPR (co->ext.open->id);
5156 WALK_SUBEXPR (co->ext.open->newunit);
5157 WALK_SUBEXPR (co->ext.open->share);
5158 WALK_SUBEXPR (co->ext.open->cc);
5159 break;
5161 case EXEC_CLOSE:
5162 WALK_SUBEXPR (co->ext.close->unit);
5163 WALK_SUBEXPR (co->ext.close->status);
5164 WALK_SUBEXPR (co->ext.close->iostat);
5165 WALK_SUBEXPR (co->ext.close->iomsg);
5166 break;
5168 case EXEC_BACKSPACE:
5169 case EXEC_ENDFILE:
5170 case EXEC_REWIND:
5171 case EXEC_FLUSH:
5172 WALK_SUBEXPR (co->ext.filepos->unit);
5173 WALK_SUBEXPR (co->ext.filepos->iostat);
5174 WALK_SUBEXPR (co->ext.filepos->iomsg);
5175 break;
5177 case EXEC_INQUIRE:
5178 WALK_SUBEXPR (co->ext.inquire->unit);
5179 WALK_SUBEXPR (co->ext.inquire->file);
5180 WALK_SUBEXPR (co->ext.inquire->iomsg);
5181 WALK_SUBEXPR (co->ext.inquire->iostat);
5182 WALK_SUBEXPR (co->ext.inquire->exist);
5183 WALK_SUBEXPR (co->ext.inquire->opened);
5184 WALK_SUBEXPR (co->ext.inquire->number);
5185 WALK_SUBEXPR (co->ext.inquire->named);
5186 WALK_SUBEXPR (co->ext.inquire->name);
5187 WALK_SUBEXPR (co->ext.inquire->access);
5188 WALK_SUBEXPR (co->ext.inquire->sequential);
5189 WALK_SUBEXPR (co->ext.inquire->direct);
5190 WALK_SUBEXPR (co->ext.inquire->form);
5191 WALK_SUBEXPR (co->ext.inquire->formatted);
5192 WALK_SUBEXPR (co->ext.inquire->unformatted);
5193 WALK_SUBEXPR (co->ext.inquire->recl);
5194 WALK_SUBEXPR (co->ext.inquire->nextrec);
5195 WALK_SUBEXPR (co->ext.inquire->blank);
5196 WALK_SUBEXPR (co->ext.inquire->position);
5197 WALK_SUBEXPR (co->ext.inquire->action);
5198 WALK_SUBEXPR (co->ext.inquire->read);
5199 WALK_SUBEXPR (co->ext.inquire->write);
5200 WALK_SUBEXPR (co->ext.inquire->readwrite);
5201 WALK_SUBEXPR (co->ext.inquire->delim);
5202 WALK_SUBEXPR (co->ext.inquire->encoding);
5203 WALK_SUBEXPR (co->ext.inquire->pad);
5204 WALK_SUBEXPR (co->ext.inquire->iolength);
5205 WALK_SUBEXPR (co->ext.inquire->convert);
5206 WALK_SUBEXPR (co->ext.inquire->strm_pos);
5207 WALK_SUBEXPR (co->ext.inquire->asynchronous);
5208 WALK_SUBEXPR (co->ext.inquire->decimal);
5209 WALK_SUBEXPR (co->ext.inquire->pending);
5210 WALK_SUBEXPR (co->ext.inquire->id);
5211 WALK_SUBEXPR (co->ext.inquire->sign);
5212 WALK_SUBEXPR (co->ext.inquire->size);
5213 WALK_SUBEXPR (co->ext.inquire->round);
5214 break;
5216 case EXEC_WAIT:
5217 WALK_SUBEXPR (co->ext.wait->unit);
5218 WALK_SUBEXPR (co->ext.wait->iostat);
5219 WALK_SUBEXPR (co->ext.wait->iomsg);
5220 WALK_SUBEXPR (co->ext.wait->id);
5221 break;
5223 case EXEC_READ:
5224 case EXEC_WRITE:
5225 WALK_SUBEXPR (co->ext.dt->io_unit);
5226 WALK_SUBEXPR (co->ext.dt->format_expr);
5227 WALK_SUBEXPR (co->ext.dt->rec);
5228 WALK_SUBEXPR (co->ext.dt->advance);
5229 WALK_SUBEXPR (co->ext.dt->iostat);
5230 WALK_SUBEXPR (co->ext.dt->size);
5231 WALK_SUBEXPR (co->ext.dt->iomsg);
5232 WALK_SUBEXPR (co->ext.dt->id);
5233 WALK_SUBEXPR (co->ext.dt->pos);
5234 WALK_SUBEXPR (co->ext.dt->asynchronous);
5235 WALK_SUBEXPR (co->ext.dt->blank);
5236 WALK_SUBEXPR (co->ext.dt->decimal);
5237 WALK_SUBEXPR (co->ext.dt->delim);
5238 WALK_SUBEXPR (co->ext.dt->pad);
5239 WALK_SUBEXPR (co->ext.dt->round);
5240 WALK_SUBEXPR (co->ext.dt->sign);
5241 WALK_SUBEXPR (co->ext.dt->extra_comma);
5242 break;
5244 case EXEC_OMP_PARALLEL:
5245 case EXEC_OMP_PARALLEL_DO:
5246 case EXEC_OMP_PARALLEL_DO_SIMD:
5247 case EXEC_OMP_PARALLEL_SECTIONS:
5249 in_omp_workshare = false;
5251 /* This goto serves as a shortcut to avoid code
5252 duplication or a larger if or switch statement. */
5253 goto check_omp_clauses;
5255 case EXEC_OMP_WORKSHARE:
5256 case EXEC_OMP_PARALLEL_WORKSHARE:
5258 in_omp_workshare = true;
5260 /* Fall through */
5262 case EXEC_OMP_CRITICAL:
5263 case EXEC_OMP_DISTRIBUTE:
5264 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
5265 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
5266 case EXEC_OMP_DISTRIBUTE_SIMD:
5267 case EXEC_OMP_DO:
5268 case EXEC_OMP_DO_SIMD:
5269 case EXEC_OMP_ORDERED:
5270 case EXEC_OMP_SECTIONS:
5271 case EXEC_OMP_SINGLE:
5272 case EXEC_OMP_END_SINGLE:
5273 case EXEC_OMP_SIMD:
5274 case EXEC_OMP_TASKLOOP:
5275 case EXEC_OMP_TASKLOOP_SIMD:
5276 case EXEC_OMP_TARGET:
5277 case EXEC_OMP_TARGET_DATA:
5278 case EXEC_OMP_TARGET_ENTER_DATA:
5279 case EXEC_OMP_TARGET_EXIT_DATA:
5280 case EXEC_OMP_TARGET_PARALLEL:
5281 case EXEC_OMP_TARGET_PARALLEL_DO:
5282 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
5283 case EXEC_OMP_TARGET_SIMD:
5284 case EXEC_OMP_TARGET_TEAMS:
5285 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
5286 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
5287 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5288 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
5289 case EXEC_OMP_TARGET_UPDATE:
5290 case EXEC_OMP_TASK:
5291 case EXEC_OMP_TEAMS:
5292 case EXEC_OMP_TEAMS_DISTRIBUTE:
5293 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
5294 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
5295 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
5297 /* Come to this label only from the
5298 EXEC_OMP_PARALLEL_* cases above. */
5300 check_omp_clauses:
5302 if (co->ext.omp_clauses)
5304 gfc_omp_namelist *n;
5305 static int list_types[]
5306 = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
5307 OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
5308 size_t idx;
5309 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
5310 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
5311 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
5312 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
5313 WALK_SUBEXPR (co->ext.omp_clauses->safelen_expr);
5314 WALK_SUBEXPR (co->ext.omp_clauses->simdlen_expr);
5315 WALK_SUBEXPR (co->ext.omp_clauses->num_teams);
5316 WALK_SUBEXPR (co->ext.omp_clauses->device);
5317 WALK_SUBEXPR (co->ext.omp_clauses->thread_limit);
5318 WALK_SUBEXPR (co->ext.omp_clauses->dist_chunk_size);
5319 WALK_SUBEXPR (co->ext.omp_clauses->grainsize);
5320 WALK_SUBEXPR (co->ext.omp_clauses->hint);
5321 WALK_SUBEXPR (co->ext.omp_clauses->num_tasks);
5322 WALK_SUBEXPR (co->ext.omp_clauses->priority);
5323 for (idx = 0; idx < OMP_IF_LAST; idx++)
5324 WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
5325 for (idx = 0;
5326 idx < sizeof (list_types) / sizeof (list_types[0]);
5327 idx++)
5328 for (n = co->ext.omp_clauses->lists[list_types[idx]];
5329 n; n = n->next)
5330 WALK_SUBEXPR (n->expr);
5332 break;
5333 default:
5334 break;
5337 WALK_SUBEXPR (co->expr1);
5338 WALK_SUBEXPR (co->expr2);
5339 WALK_SUBEXPR (co->expr3);
5340 WALK_SUBEXPR (co->expr4);
5341 for (b = co->block; b; b = b->block)
5343 WALK_SUBEXPR (b->expr1);
5344 WALK_SUBEXPR (b->expr2);
5345 WALK_SUBCODE (b->next);
5348 if (co->op == EXEC_FORALL)
5349 forall_level --;
5351 if (co->op == EXEC_DO)
5352 doloop_level --;
5354 if (co->op == EXEC_IF)
5355 if_level --;
5357 if (co->op == EXEC_SELECT)
5358 select_level --;
5360 in_omp_workshare = saved_in_omp_workshare;
5361 in_where = saved_in_where;
5364 return 0;
5367 /* As a post-resolution step, check that all global symbols which are
5368 not declared in the source file match in their call signatures.
5369 We do this by looping over the code (and expressions). The first call
5370 we happen to find is assumed to be canonical. */
5373 /* Common tests for argument checking for both functions and subroutines. */
5375 static int
5376 check_externals_procedure (gfc_symbol *sym, locus *loc, gfc_actual_arglist *actual)
5378 gfc_gsymbol *gsym;
5379 gfc_symbol *def_sym = NULL;
5381 if (sym == NULL || sym->attr.is_bind_c)
5382 return 0;
5384 if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN)
5385 return 0;
5387 if (sym->attr.if_source == IFSRC_IFBODY || sym->attr.if_source == IFSRC_DECL)
5388 return 0;
5390 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
5391 if (gsym == NULL)
5392 return 0;
5394 if (gsym->ns)
5395 gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym);
5397 if (def_sym)
5399 gfc_procedure_use (def_sym, &actual, loc);
5400 return 0;
5403 /* First time we have seen this procedure called. Let's create an
5404 "interface" from the call and put it into a new namespace. */
5405 gfc_namespace *save_ns;
5406 gfc_symbol *new_sym;
5408 gsym->where = *loc;
5409 save_ns = gfc_current_ns;
5410 gsym->ns = gfc_get_namespace (gfc_current_ns, 0);
5411 gsym->ns->proc_name = sym;
5413 gfc_get_symbol (sym->name, gsym->ns, &new_sym);
5414 gcc_assert (new_sym);
5415 new_sym->attr = sym->attr;
5416 new_sym->attr.if_source = IFSRC_DECL;
5417 gfc_current_ns = gsym->ns;
5419 gfc_get_formal_from_actual_arglist (new_sym, actual);
5420 gfc_current_ns = save_ns;
5422 return 0;
5426 /* Callback for calls of external routines. */
5428 static int
5429 check_externals_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
5430 void *data ATTRIBUTE_UNUSED)
5432 gfc_code *co = *c;
5433 gfc_symbol *sym;
5434 locus *loc;
5435 gfc_actual_arglist *actual;
5437 if (co->op != EXEC_CALL)
5438 return 0;
5440 sym = co->resolved_sym;
5441 loc = &co->loc;
5442 actual = co->ext.actual;
5444 return check_externals_procedure (sym, loc, actual);
5448 /* Callback for external functions. */
5450 static int
5451 check_externals_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
5452 void *data ATTRIBUTE_UNUSED)
5454 gfc_expr *e = *ep;
5455 gfc_symbol *sym;
5456 locus *loc;
5457 gfc_actual_arglist *actual;
5459 if (e->expr_type != EXPR_FUNCTION)
5460 return 0;
5462 sym = e->value.function.esym;
5463 if (sym == NULL)
5464 return 0;
5466 loc = &e->where;
5467 actual = e->value.function.actual;
5469 return check_externals_procedure (sym, loc, actual);
5472 /* Called routine. */
5474 void
5475 gfc_check_externals (gfc_namespace *ns)
5478 gfc_clear_error ();
5480 /* Turn errors into warnings if the user indicated this. */
5482 if (!pedantic && flag_allow_argument_mismatch)
5483 gfc_errors_to_warnings (true);
5485 gfc_code_walker (&ns->code, check_externals_code, check_externals_expr, NULL);
5487 for (ns = ns->contained; ns; ns = ns->sibling)
5489 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
5490 gfc_check_externals (ns);
5493 gfc_errors_to_warnings (false);