]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/fortran/frontend-passes.c
re PR fortran/91557 (Bogus warning about unused dummy argument _formal_*)
[thirdparty/gcc.git] / gcc / fortran / frontend-passes.c
1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2019 Free Software Foundation, Inc.
3 Contributed by Thomas König.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
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"
29
30 /* Forward declarations. */
31
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);
60
61 #ifdef CHECKING_P
62 static void check_locus (gfc_namespace *);
63 #endif
64
65 /* How deep we are inside an argument list. */
66
67 static int count_arglist;
68
69 /* Vector of gfc_expr ** we operate on. */
70
71 static vec<gfc_expr **> expr_array;
72
73 /* Pointer to the gfc_code we currently work on - to be able to insert
74 a block before the statement. */
75
76 static gfc_code **current_code;
77
78 /* Pointer to the block to be inserted, and the statement we are
79 changing within the block. */
80
81 static gfc_code *inserted_block, **changed_statement;
82
83 /* The namespace we are currently dealing with. */
84
85 static gfc_namespace *current_ns;
86
87 /* If we are within any forall loop. */
88
89 static int forall_level;
90
91 /* Keep track of whether we are within an OMP workshare. */
92
93 static bool in_omp_workshare;
94
95 /* Keep track of whether we are within a WHERE statement. */
96
97 static bool in_where;
98
99 /* Keep track of iterators for array constructors. */
100
101 static int iterator_level;
102
103 /* Keep track of DO loop levels. */
104
105 typedef struct {
106 gfc_code *c;
107 int branch_level;
108 bool seen_goto;
109 } do_t;
110
111 static vec<do_t> doloop_list;
112 static int doloop_level;
113
114 /* Keep track of if and select case levels. */
115
116 static int if_level;
117 static int select_level;
118
119 /* Vector of gfc_expr * to keep track of DO loops. */
120
121 struct my_struct *evec;
122
123 /* Keep track of association lists. */
124
125 static bool in_assoc_list;
126
127 /* Counter for temporary variables. */
128
129 static int var_num = 1;
130
131 /* What sort of matrix we are dealing with when inlining MATMUL. */
132
133 enum matrix_case { none=0, A2B2, A2B1, A1B2, A2B2T, A2TB2, A2TB2T };
134
135 /* Keep track of the number of expressions we have inserted so far
136 using create_var. */
137
138 int n_vars;
139
140 /* Entry point - run all passes for a namespace. */
141
142 void
143 gfc_run_passes (gfc_namespace *ns)
144 {
145
146 /* Warn about dubious DO loops where the index might
147 change. */
148
149 doloop_level = 0;
150 if_level = 0;
151 select_level = 0;
152 doloop_warn (ns);
153 doloop_list.release ();
154 int w, e;
155
156 #ifdef CHECKING_P
157 check_locus (ns);
158 #endif
159
160 gfc_get_errors (&w, &e);
161 if (e > 0)
162 return;
163
164 if (flag_frontend_optimize || flag_frontend_loop_interchange)
165 optimize_namespace (ns);
166
167 if (flag_frontend_optimize)
168 {
169 optimize_reduction (ns);
170 if (flag_dump_fortran_optimized)
171 gfc_dump_parse_tree (ns, stdout);
172
173 expr_array.release ();
174 }
175
176 if (flag_realloc_lhs)
177 realloc_strings (ns);
178 }
179
180 #ifdef CHECKING_P
181
182 /* Callback function: Warn if there is no location information in a
183 statement. */
184
185 static int
186 check_locus_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
187 void *data ATTRIBUTE_UNUSED)
188 {
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");
193
194 return 0;
195 }
196
197
198 /* Callback function: Warn if there is no location information in an
199 expression. */
200
201 static int
202 check_locus_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
203 void *data ATTRIBUTE_UNUSED)
204 {
205
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;
211 }
212
213 /* Run check for missing location information. */
214
215 static void
216 check_locus (gfc_namespace *ns)
217 {
218 gfc_code_walker (&ns->code, check_locus_code, check_locus_expr, NULL);
219
220 for (ns = ns->contained; ns; ns = ns->sibling)
221 {
222 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
223 check_locus (ns);
224 }
225 }
226
227 #endif
228
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
232
233 a = a(x:y)
234
235 with
236
237 tmp = a(x:y)
238 a = tmp
239 */
240
241 static int
242 realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
243 void *data ATTRIBUTE_UNUSED)
244 {
245 gfc_expr *expr1, *expr2;
246 gfc_code *co = *c;
247 gfc_expr *n;
248 gfc_ref *ref;
249 bool found_substr;
250
251 if (co->op != EXEC_ASSIGN)
252 return 0;
253
254 expr1 = co->expr1;
255 if (expr1->ts.type != BT_CHARACTER
256 || !gfc_expr_attr(expr1).allocatable
257 || !expr1->ts.deferred)
258 return 0;
259
260 if (is_fe_temp (expr1))
261 return 0;
262
263 expr2 = gfc_discard_nops (co->expr2);
264
265 if (expr2->expr_type == EXPR_VARIABLE)
266 {
267 found_substr = false;
268 for (ref = expr2->ref; ref; ref = ref->next)
269 {
270 if (ref->type == REF_SUBSTRING)
271 {
272 found_substr = true;
273 break;
274 }
275 }
276 if (!found_substr)
277 return 0;
278 }
279 else if (expr2->expr_type != EXPR_ARRAY
280 && (expr2->expr_type != EXPR_OP
281 || expr2->value.op.op != INTRINSIC_CONCAT))
282 return 0;
283
284 if (!gfc_check_dependency (expr1, expr2, true))
285 return 0;
286
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;
293
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;
300 }
301
302 /* Callback for each gfc_code node invoked through gfc_code_walker
303 from optimize_namespace. */
304
305 static int
306 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
307 void *data ATTRIBUTE_UNUSED)
308 {
309
310 gfc_exec_op op;
311
312 op = (*c)->op;
313
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;
319
320 current_code = c;
321 inserted_block = NULL;
322 changed_statement = NULL;
323
324 if (op == EXEC_ASSIGN)
325 optimize_assignment (*c);
326 return 0;
327 }
328
329 /* Callback for each gfc_expr node invoked through gfc_code_walker
330 from optimize_namespace. */
331
332 static int
333 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
334 void *data ATTRIBUTE_UNUSED)
335 {
336 bool function_expr;
337
338 if ((*e)->expr_type == EXPR_FUNCTION)
339 {
340 count_arglist ++;
341 function_expr = true;
342 }
343 else
344 function_expr = false;
345
346 if (optimize_trim (*e))
347 gfc_simplify_expr (*e, 0);
348
349 if (optimize_lexical_comparison (*e))
350 gfc_simplify_expr (*e, 0);
351
352 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
353 gfc_simplify_expr (*e, 0);
354
355 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
356 switch ((*e)->value.function.isym->id)
357 {
358 case GFC_ISYM_MINLOC:
359 case GFC_ISYM_MAXLOC:
360 optimize_minmaxloc (e);
361 break;
362 default:
363 break;
364 }
365
366 if (function_expr)
367 count_arglist --;
368
369 return 0;
370 }
371
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. */
375
376 static gfc_expr *
377 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
378 {
379 gfc_expr *fcn, *e = c->expr;
380
381 fcn = gfc_copy_expr (e);
382 if (c->iterator)
383 {
384 gfc_constructor_base newbase;
385 gfc_expr *new_expr;
386 gfc_constructor *new_c;
387
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;
398
399 fcn = new_expr;
400 }
401
402 if (fcn->rank != 0)
403 {
404 gfc_isym_id id = fn->value.function.isym->id;
405
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");
416
417 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
418 }
419
420 return fcn;
421 }
422
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. */
426
427 static int
428 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
429 void *data ATTRIBUTE_UNUSED)
430 {
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;
439
440 fn = *e;
441
442 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
443 || fn->value.function.isym == NULL)
444 return 0;
445
446 id = fn->value.function.isym->id;
447
448 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
449 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
450 return 0;
451
452 a = fn->value.function.actual;
453
454 /* Don't handle MASK or DIM. */
455
456 dim = a->next;
457
458 if (dim->expr != NULL)
459 return 0;
460
461 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
462 {
463 mask = dim->next;
464 if ( mask->expr != NULL)
465 return 0;
466 }
467
468 arg = a->expr;
469
470 if (arg->expr_type != EXPR_ARRAY)
471 return 0;
472
473 switch (id)
474 {
475 case GFC_ISYM_SUM:
476 op = INTRINSIC_PLUS;
477 break;
478
479 case GFC_ISYM_PRODUCT:
480 op = INTRINSIC_TIMES;
481 break;
482
483 case GFC_ISYM_ANY:
484 op = INTRINSIC_OR;
485 break;
486
487 case GFC_ISYM_ALL:
488 op = INTRINSIC_AND;
489 break;
490
491 default:
492 return 0;
493 }
494
495 c = gfc_constructor_first (arg->value.constructor);
496
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. */
501
502 if (c == NULL)
503 return 0;
504
505 res = copy_walk_reduction_arg (c, fn);
506
507 c = gfc_constructor_next (c);
508 while (c)
509 {
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);
520 }
521
522 gfc_simplify_expr (res, 0);
523 *e = res;
524 gfc_free_expr (fn);
525
526 return 0;
527 }
528
529 /* Callback function for common function elimination, called from cfe_expr_0.
530 Put all eligible function expressions into expr_array. */
531
532 static int
533 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
534 void *data ATTRIBUTE_UNUSED)
535 {
536
537 if ((*e)->expr_type != EXPR_FUNCTION)
538 return 0;
539
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;
545
546 /* We don't do function elimination within FORALL statements, it can
547 lead to wrong-code in certain circumstances. */
548
549 if (forall_level > 0)
550 return 0;
551
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. */
555
556 if (iterator_level > 0)
557 return 0;
558
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. */
562
563 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
564 return 0;
565
566 /* Skip the test for pure functions if -faggressive-function-elimination
567 is specified. */
568 if ((*e)->value.function.esym)
569 {
570 /* Don't create an array temporary for elemental functions. */
571 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
572 return 0;
573
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;
580 }
581
582 if ((*e)->value.function.isym)
583 {
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;
590
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;
596
597 if (!(*e)->value.function.isym->pure)
598 return 0;
599 }
600
601 expr_array.safe_push (e);
602 return 0;
603 }
604
605 /* Auxiliary function to check if an expression is a temporary created by
606 create var. */
607
608 static bool
609 is_fe_temp (gfc_expr *e)
610 {
611 if (e->expr_type != EXPR_VARIABLE)
612 return false;
613
614 return e->symtree->n.sym->attr.fe_temp;
615 }
616
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. */
622
623 static gfc_expr *
624 constant_string_length (gfc_expr *e)
625 {
626
627 gfc_expr *length;
628 gfc_ref *ref;
629 gfc_expr *res;
630 mpz_t value;
631
632 if (e->ts.u.cl)
633 {
634 length = e->ts.u.cl->length;
635 if (length && length->expr_type == EXPR_CONSTANT)
636 return gfc_copy_expr(length);
637 }
638
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)
642 {
643 if (ref->type == REF_SUBSTRING)
644 {
645 if (gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
646 {
647 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
648 &e->where);
649
650 mpz_add_ui (res->value.integer, value, 1);
651 mpz_clear (value);
652 return res;
653 }
654 else
655 return NULL;
656 }
657 }
658
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);
664
665 return NULL;
666
667 }
668
669 /* Insert a block at the current position unless it has already
670 been inserted; in this case use the one already there. */
671
672 static gfc_namespace*
673 insert_block ()
674 {
675 gfc_namespace *ns;
676
677 /* If the block hasn't already been created, do so. */
678 if (inserted_block == NULL)
679 {
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;
686
687 ns->code = *current_code;
688
689 /* If the statement has a label, make sure it is transferred to
690 the newly created block. */
691
692 if ((*current_code)->here)
693 {
694 inserted_block->here = (*current_code)->here;
695 (*current_code)->here = NULL;
696 }
697
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;
704 }
705 else
706 ns = inserted_block->ext.block.ns;
707
708 return ns;
709 }
710
711
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. */
715
716 static gfc_expr*
717 get_len_call (gfc_expr *str)
718 {
719 gfc_expr *fcn;
720 gfc_actual_arglist *actual_arglist;
721
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;
727
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;
732
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);
741
742 return fcn;
743 }
744
745
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. */
752
753 static gfc_expr*
754 create_var (gfc_expr * e, const char *vname)
755 {
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;
764
765 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
766 return gfc_copy_expr (e);
767
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;
772
773 ns = insert_block ();
774
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++);
779
780 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
781 gcc_unreachable ();
782
783 symbol = symtree->n.sym;
784 symbol->ts = e->ts;
785
786 if (e->rank > 0)
787 {
788 symbol->as = gfc_get_array_spec ();
789 symbol->as->rank = e->rank;
790
791 if (e->shape == NULL)
792 {
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;
797 }
798 else
799 {
800 symbol->as->type = AS_EXPLICIT;
801 /* Copy the shape. */
802 for (i=0; i<e->rank; i++)
803 {
804 gfc_expr *p, *q;
805
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;
810
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;
815 }
816 }
817 }
818
819 deferred = 0;
820 if (e->ts.type == BT_CHARACTER)
821 {
822 gfc_expr *length;
823
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
833 {
834 symbol->attr.allocatable = 1;
835 symbol->ts.u.cl->length = NULL;
836 symbol->ts.deferred = 1;
837 deferred = 1;
838 }
839 }
840
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);
846
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)
856 {
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));
867 }
868
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 ++;
878
879 return result;
880 }
881
882 /* Warn about function elimination. */
883
884 static void
885 do_warn_function_elimination (gfc_expr *e)
886 {
887 const char *name;
888 if (e->expr_type == EXPR_FUNCTION
889 && !gfc_pure_function (e, &name) && !gfc_implicit_pure_function (e))
890 {
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));
899 }
900 }
901
902
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. */
907
908 static int
909 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
910 void *data ATTRIBUTE_UNUSED)
911 {
912 int i,j;
913 gfc_expr *newvar;
914 gfc_expr **ei, **ej;
915
916 /* Don't do this optimization within OMP workshare or ASSOC lists. */
917
918 if (in_omp_workshare || in_assoc_list)
919 {
920 *walk_subtrees = 0;
921 return 0;
922 }
923
924 expr_array.release ();
925
926 gfc_expr_walker (e, cfe_register_funcs, NULL);
927
928 /* Walk through all the functions. */
929
930 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
931 {
932 /* Skip if the function has been replaced by a variable already. */
933 if ((*ei)->expr_type == EXPR_VARIABLE)
934 continue;
935
936 newvar = NULL;
937 for (j=0; j<i; j++)
938 {
939 ej = expr_array[j];
940 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
941 {
942 if (newvar == NULL)
943 newvar = create_var (*ei, "fcn");
944
945 if (warn_function_elimination)
946 do_warn_function_elimination (*ej);
947
948 free (*ej);
949 *ej = gfc_copy_expr (newvar);
950 }
951 }
952 if (newvar)
953 *ei = newvar;
954 }
955
956 /* We did all the necessary walking in this function. */
957 *walk_subtrees = 0;
958 return 0;
959 }
960
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. */
964
965 static int
966 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
967 {
968 current_code = c;
969 inserted_block = NULL;
970 changed_statement = NULL;
971
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
975
976 WHERE (a>0)
977 b = sum(foo(a) + foo(a))
978 END WHERE
979
980 with
981
982 WHERE (a > 0)
983 tmp = foo(a)
984 b = sum(tmp + tmp)
985 END WHERE
986 */
987
988 if ((*c)->op == EXEC_WHERE)
989 {
990 *walk_subtrees = 0;
991 return 0;
992 }
993
994
995 return 0;
996 }
997
998 /* Dummy function for expression call back, for use when we
999 really don't want to do any walking. */
1000
1001 static int
1002 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
1003 void *data ATTRIBUTE_UNUSED)
1004 {
1005 *walk_subtrees = 0;
1006 return 0;
1007 }
1008
1009 /* Dummy function for code callback, for use when we really
1010 don't want to do anything. */
1011 int
1012 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
1013 int *walk_subtrees ATTRIBUTE_UNUSED,
1014 void *data ATTRIBUTE_UNUSED)
1015 {
1016 return 0;
1017 }
1018
1019 /* Code callback function for converting
1020 do while(a)
1021 end do
1022 into the equivalent
1023 do
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. */
1028
1029 static int
1030 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1031 void *data ATTRIBUTE_UNUSED)
1032 {
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;
1037
1038 if (co->op != EXEC_DO_WHILE)
1039 return 0;
1040
1041 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
1042 return 0;
1043
1044 e_cond = co->expr1;
1045
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;
1054
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;
1060
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;
1067
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;
1073
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);
1077
1078 /* Hang the generated if statement into the loop body. */
1079
1080 loopblock = co->block->next;
1081 co->block->next = c_if1;
1082 c_if1->next = loopblock;
1083
1084 return 0;
1085 }
1086
1087 /* Code callback function for converting
1088 if (a) then
1089 ...
1090 else if (b) then
1091 end if
1092
1093 into
1094 if (a) then
1095 else
1096 if (b) then
1097 end if
1098 end if
1099
1100 because otherwise common function elimination would place the BLOCKs
1101 into the wrong place. */
1102
1103 static int
1104 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1105 void *data ATTRIBUTE_UNUSED)
1106 {
1107 gfc_code *co = *c;
1108 gfc_code *c_if1, *c_if2, *else_stmt;
1109
1110 if (co->op != EXEC_IF)
1111 return 0;
1112
1113 /* This loop starts out with the first ELSE statement. */
1114 else_stmt = co->block->block;
1115
1116 while (else_stmt != NULL)
1117 {
1118 gfc_code *next_else;
1119
1120 /* If there is no condition, we're done. */
1121 if (else_stmt->expr1 == NULL)
1122 break;
1123
1124 next_else = else_stmt->block;
1125
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;
1133
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;
1139
1140 /* Insert the new IF after the ELSE. */
1141 else_stmt->expr1 = NULL;
1142 else_stmt->next = c_if1;
1143 else_stmt->block = NULL;
1144
1145 else_stmt = next_else;
1146 }
1147 /* Don't walk subtrees. */
1148 return 0;
1149 }
1150
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)
1156 {
1157 gfc_expr *expr1 = (gfc_expr *) data;
1158 gfc_expr *expr2 = *e;
1159
1160 if (expr2->expr_type != EXPR_VARIABLE)
1161 return 0;
1162
1163 return expr1->symtree->n.sym == expr2->symtree->n.sym;
1164 }
1165
1166 /* Return true if expr1 is found in expr2. */
1167
1168 static bool
1169 var_in_expr (gfc_expr *expr1, gfc_expr *expr2)
1170 {
1171 gcc_assert (expr1->expr_type == EXPR_VARIABLE);
1172
1173 return gfc_expr_walker (&expr2, var_in_expr_callback, (void *) expr1);
1174 }
1175
1176 struct do_stack
1177 {
1178 struct do_stack *prev;
1179 gfc_iterator *iter;
1180 gfc_code *code;
1181 } *stack_top;
1182
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:
1186
1187 write (*,*) (a(i), i=1,4)
1188
1189 is replaced with
1190
1191 write (*,*) a(1:4:1) . */
1192
1193 static bool
1194 traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
1195 {
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;
1203
1204 /* Find the first transfer/do statement. */
1205 for (curr = code; curr; curr = curr->next)
1206 {
1207 if (curr->op == EXEC_DO || curr->op == EXEC_TRANSFER)
1208 break;
1209 }
1210
1211 /* Ensure it is the only transfer/do statement because cases like
1212
1213 write (*,*) (a(i), b(i), i=1,4)
1214
1215 cannot be optimized. */
1216
1217 if (!curr || curr->next)
1218 return false;
1219
1220 if (curr->op == EXEC_DO)
1221 {
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))
1229 {
1230 if (curr != stack_top->code && !*has_reached)
1231 {
1232 curr->block->next = NULL;
1233 gfc_free_statements (curr);
1234 }
1235 else
1236 *has_reached = true;
1237 return true;
1238 }
1239 return false;
1240 }
1241
1242 gcc_assert (curr->op == EXEC_TRANSFER);
1243
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;
1248
1249 /* Find the iterators belonging to each variable and check conditions. */
1250 for (i = 0; i < ref->u.ar.dimen; i++)
1251 {
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;
1255
1256 start = ref->u.ar.start[i];
1257 gfc_simplify_expr (start, 0);
1258 switch (start->expr_type)
1259 {
1260 case EXPR_VARIABLE:
1261
1262 /* write (*,*) (a(i), i=a%b,1) not handled yet. */
1263 if (start->ref)
1264 return false;
1265
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)
1269 {
1270 /* Check for (a(i,i), i=1,3). */
1271 int j;
1272
1273 for (j=0; j<i; j++)
1274 if (iters[j] && iters[j]->var->symtree == start->symtree)
1275 return false;
1276
1277 iters[i] = NULL;
1278 }
1279 else
1280 {
1281 iters[i] = stack_top->iter;
1282 stack_top = stack_top->prev;
1283 future_rank++;
1284 }
1285 break;
1286 case EXPR_CONSTANT:
1287 iters[i] = NULL;
1288 break;
1289 case EXPR_OP:
1290 switch (start->value.op.op)
1291 {
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;
1311 }
1312 future_rank++;
1313 break;
1314 default:
1315 return false;
1316 }
1317 }
1318
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++)
1321 {
1322 if (iters[i])
1323 {
1324 gfc_expr *var = iters[i]->var;
1325 for (int j = i - 1; j < i; j++)
1326 {
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;
1332 }
1333 }
1334 }
1335
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);
1342
1343 /* Assign new starts, ends and strides if necessary. */
1344 for (i = 0; i < ref->u.ar.dimen; i++)
1345 {
1346 if (!iters[i])
1347 continue;
1348 start = ref->u.ar.start[i];
1349 switch (start->expr_type)
1350 {
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)
1375 {
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");
1388 }
1389 break;
1390 default:
1391 gfc_internal_error ("bad expression");
1392 }
1393 }
1394 curr->expr1 = new_e;
1395
1396 /* Insert modified statement. Check whether the statement needs to be
1397 inserted at the lowest level. */
1398 if (!stack_top->iter)
1399 {
1400 if (prev)
1401 {
1402 curr->next = prev->next->next;
1403 prev->next = curr;
1404 }
1405 else
1406 {
1407 curr->next = stack_top->code->block->next->next->next;
1408 stack_top->code->block->next = curr;
1409 }
1410 }
1411 else
1412 stack_top->code->block->next = curr;
1413 return true;
1414 }
1415
1416 /* Function for the gfc_code_walker. If code is a READ or WRITE statement, it
1417 tries to optimize its block. */
1418
1419 static int
1420 simplify_io_impl_do (gfc_code **code, int *walk_subtrees,
1421 void *data ATTRIBUTE_UNUSED)
1422 {
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;
1431
1432 *walk_subtrees = 0;
1433 write.prev = NULL;
1434 write.iter = NULL;
1435 write.code = *code;
1436
1437 for (curr = &(*code)->block; *curr; curr = &(*curr)->next)
1438 {
1439 if ((*curr)->op == EXEC_DO)
1440 {
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;
1447 }
1448 prev = *curr;
1449 }
1450 return 0;
1451 }
1452
1453 /* Optimize a namespace, including all contained namespaces.
1454 flag_frontend_optimize and flag_fronend_loop_interchange are
1455 handled separately. */
1456
1457 static void
1458 optimize_namespace (gfc_namespace *ns)
1459 {
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;
1467
1468 if (flag_frontend_optimize)
1469 {
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)
1476 {
1477 bool found;
1478 do
1479 {
1480 found = false;
1481 gfc_code_walker (&ns->code, matmul_to_var_code, matmul_to_var_expr,
1482 (void *) &found);
1483 }
1484 while (found);
1485
1486 gfc_code_walker (&ns->code, matmul_temp_args, dummy_expr_callback,
1487 NULL);
1488 }
1489
1490 if (flag_external_blas)
1491 gfc_code_walker (&ns->code, call_external_blas, dummy_expr_callback,
1492 NULL);
1493
1494 if (flag_inline_matmul_limit != 0)
1495 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
1496 NULL);
1497 }
1498
1499 if (flag_frontend_loop_interchange)
1500 gfc_code_walker (&ns->code, index_interchange, dummy_expr_callback,
1501 NULL);
1502
1503 /* BLOCKs are handled in the expression walker below. */
1504 for (ns = ns->contained; ns; ns = ns->sibling)
1505 {
1506 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1507 optimize_namespace (ns);
1508 }
1509 gfc_current_ns = saved_ns;
1510 }
1511
1512 /* Handle dependencies for allocatable strings which potentially redefine
1513 themselves in an assignment. */
1514
1515 static void
1516 realloc_strings (gfc_namespace *ns)
1517 {
1518 current_ns = ns;
1519 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1520
1521 for (ns = ns->contained; ns; ns = ns->sibling)
1522 {
1523 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1524 realloc_strings (ns);
1525 }
1526
1527 }
1528
1529 static void
1530 optimize_reduction (gfc_namespace *ns)
1531 {
1532 current_ns = ns;
1533 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1534 callback_reduction, NULL);
1535
1536 /* BLOCKs are handled in the expression walker below. */
1537 for (ns = ns->contained; ns; ns = ns->sibling)
1538 {
1539 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1540 optimize_reduction (ns);
1541 }
1542 }
1543
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.
1550 */
1551
1552 static bool
1553 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1554 {
1555 gfc_expr *e;
1556
1557 if (!*rhs)
1558 return false;
1559
1560 e = *rhs;
1561 if (e->expr_type == EXPR_OP)
1562 {
1563 switch (e->value.op.op)
1564 {
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;
1575
1576 case INTRINSIC_CONCAT:
1577 /* Do not do string concatenations. */
1578 break;
1579
1580 default:
1581 /* Binary operators. */
1582 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1583 return true;
1584
1585 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1586 return true;
1587
1588 break;
1589 }
1590 }
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))
1602 {
1603
1604 gfc_code *n;
1605 gfc_expr *new_expr;
1606
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;
1613
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;
1619
1620 return true;
1621
1622 }
1623
1624 /* Nothing to optimize. */
1625 return false;
1626 }
1627
1628 /* Remove unneeded TRIMs at the end of expressions. */
1629
1630 static bool
1631 remove_trim (gfc_expr *rhs)
1632 {
1633 bool ret;
1634
1635 ret = false;
1636 if (!rhs)
1637 return ret;
1638
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. */
1642
1643 while (rhs->expr_type == EXPR_OP
1644 && rhs->value.op.op == INTRINSIC_CONCAT)
1645 rhs = rhs->value.op.op2;
1646
1647 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1648 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1649 {
1650 strip_function_call (rhs);
1651 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1652 remove_trim (rhs);
1653 ret = true;
1654 }
1655
1656 return ret;
1657 }
1658
1659 /* Optimizations for an assignment. */
1660
1661 static void
1662 optimize_assignment (gfc_code * c)
1663 {
1664 gfc_expr *lhs, *rhs;
1665
1666 lhs = c->expr1;
1667 rhs = c->expr2;
1668
1669 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1670 {
1671 /* Optimize a = trim(b) to a = b. */
1672 remove_trim (rhs);
1673
1674 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1675 if (is_empty_string (rhs))
1676 rhs->value.character.length = 0;
1677 }
1678
1679 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1680 optimize_binop_array_assignment (c, &rhs, false);
1681 }
1682
1683
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. */
1687
1688 static void
1689 strip_function_call (gfc_expr *e)
1690 {
1691 gfc_expr *e1;
1692 gfc_actual_arglist *a;
1693
1694 a = e->value.function.actual;
1695
1696 /* We should have at least one argument. */
1697 gcc_assert (a->expr != NULL);
1698
1699 e1 = a->expr;
1700
1701 /* Free the remaining arglist, if any. */
1702 if (a->next)
1703 gfc_free_actual_arglist (a->next);
1704
1705 /* Graft the argument expression onto the original function. */
1706 *e = *e1;
1707 free (e1);
1708
1709 }
1710
1711 /* Optimization of lexical comparison functions. */
1712
1713 static bool
1714 optimize_lexical_comparison (gfc_expr *e)
1715 {
1716 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1717 return false;
1718
1719 switch (e->value.function.isym->id)
1720 {
1721 case GFC_ISYM_LLE:
1722 return optimize_comparison (e, INTRINSIC_LE);
1723
1724 case GFC_ISYM_LGE:
1725 return optimize_comparison (e, INTRINSIC_GE);
1726
1727 case GFC_ISYM_LGT:
1728 return optimize_comparison (e, INTRINSIC_GT);
1729
1730 case GFC_ISYM_LLT:
1731 return optimize_comparison (e, INTRINSIC_LT);
1732
1733 default:
1734 break;
1735 }
1736 return false;
1737 }
1738
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. */
1742
1743 static bool
1744 combine_array_constructor (gfc_expr *e)
1745 {
1746
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;
1755
1756 /* Array constructors have rank one. */
1757 if (e->rank != 1)
1758 return false;
1759
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;
1764
1765 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1766 if (forall_level > 0)
1767 return false;
1768
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;
1773
1774 /* WHERE also doesn't work. */
1775 if (in_where > 0)
1776 return false;
1777
1778 op1 = e->value.op.op1;
1779 op2 = e->value.op.op2;
1780
1781 if (!op1 || !op2)
1782 return false;
1783
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)
1787 {
1788 scalar_first = true;
1789 op1 = e->value.op.op2;
1790 op2 = e->value.op.op1;
1791 }
1792 else
1793 return false;
1794
1795 if (op2->ts.type == BT_CHARACTER)
1796 return false;
1797
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. */
1803
1804 #define CONSTR_LEN_MAX 4
1805
1806 oldbase = op1->value.constructor;
1807
1808 n_elem = 0;
1809 all_const = true;
1810 for (c = gfc_constructor_first (oldbase); c; c = gfc_constructor_next(c))
1811 {
1812 if (c->expr->expr_type != EXPR_CONSTANT)
1813 {
1814 all_const = false;
1815 break;
1816 }
1817 n_elem += 1;
1818 }
1819
1820 if (all_const && n_elem > CONSTR_LEN_MAX)
1821 return false;
1822
1823 #undef CONSTR_LEN_MAX
1824
1825 newbase = NULL;
1826 e->expr_type = EXPR_ARRAY;
1827
1828 scalar = create_var (gfc_copy_expr (op2), "constr");
1829
1830 for (c = gfc_constructor_first (oldbase); c;
1831 c = gfc_constructor_next (c))
1832 {
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;
1839
1840 if (scalar_first)
1841 {
1842 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1843 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1844 }
1845 else
1846 {
1847 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1848 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1849 }
1850
1851 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1852 new_c->iterator = c->iterator;
1853 c->iterator = NULL;
1854 }
1855
1856 gfc_free_expr (op1);
1857 gfc_free_expr (op2);
1858 gfc_free_expr (scalar);
1859
1860 e->value.constructor = newbase;
1861 return true;
1862 }
1863
1864 /* Recursive optimization of operators. */
1865
1866 static bool
1867 optimize_op (gfc_expr *e)
1868 {
1869 bool changed;
1870
1871 gfc_intrinsic_op op = e->value.op.op;
1872
1873 changed = false;
1874
1875 /* Only use new-style comparisons. */
1876 switch(op)
1877 {
1878 case INTRINSIC_EQ_OS:
1879 op = INTRINSIC_EQ;
1880 break;
1881
1882 case INTRINSIC_GE_OS:
1883 op = INTRINSIC_GE;
1884 break;
1885
1886 case INTRINSIC_LE_OS:
1887 op = INTRINSIC_LE;
1888 break;
1889
1890 case INTRINSIC_NE_OS:
1891 op = INTRINSIC_NE;
1892 break;
1893
1894 case INTRINSIC_GT_OS:
1895 op = INTRINSIC_GT;
1896 break;
1897
1898 case INTRINSIC_LT_OS:
1899 op = INTRINSIC_LT;
1900 break;
1901
1902 default:
1903 break;
1904 }
1905
1906 switch (op)
1907 {
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);
1915
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;
1923
1924 default:
1925 break;
1926 }
1927
1928 return false;
1929 }
1930
1931
1932 /* Return true if a constant string contains only blanks. */
1933
1934 static bool
1935 is_empty_string (gfc_expr *e)
1936 {
1937 int i;
1938
1939 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1940 return false;
1941
1942 for (i=0; i < e->value.character.length; i++)
1943 {
1944 if (e->value.character.string[i] != ' ')
1945 return false;
1946 }
1947
1948 return true;
1949 }
1950
1951
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. */
1955
1956 static gfc_expr*
1957 get_len_trim_call (gfc_expr *str, int kind)
1958 {
1959 gfc_expr *fcn;
1960 gfc_actual_arglist *actual_arglist, *next;
1961
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;
1970
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;
1975
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);
1984
1985 return fcn;
1986 }
1987
1988
1989 /* Optimize expressions for equality. */
1990
1991 static bool
1992 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1993 {
1994 gfc_expr *op1, *op2;
1995 bool change;
1996 int eq;
1997 bool result;
1998 gfc_actual_arglist *firstarg, *secondarg;
1999
2000 if (e->expr_type == EXPR_OP)
2001 {
2002 firstarg = NULL;
2003 secondarg = NULL;
2004 op1 = e->value.op.op1;
2005 op2 = e->value.op.op2;
2006 }
2007 else if (e->expr_type == EXPR_FUNCTION)
2008 {
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;
2014 }
2015 else
2016 gcc_unreachable ();
2017
2018 /* Strip off unneeded TRIM calls from string comparisons. */
2019
2020 change = remove_trim (op1);
2021
2022 if (remove_trim (op2))
2023 change = true;
2024
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;
2031
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))
2036 {
2037 bool empty_op1, empty_op2;
2038 empty_op1 = is_empty_string (op1);
2039 empty_op2 = is_empty_string (op2);
2040
2041 if (empty_op1 || empty_op2)
2042 {
2043 gfc_expr *fcn;
2044 gfc_expr *zero;
2045 gfc_expr *str;
2046
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;
2051
2052 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
2053 str = empty_op1 ? op2 : op1;
2054
2055 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
2056
2057
2058 if (empty_op1)
2059 gfc_free_expr (op1);
2060 else
2061 gfc_free_expr (op2);
2062
2063 op1 = fcn;
2064 op2 = zero;
2065 e->value.op.op1 = fcn;
2066 e->value.op.op2 = zero;
2067 }
2068 }
2069
2070
2071 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
2072
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))
2076 {
2077 eq = gfc_dep_compare_expr (op1, op2);
2078 if (eq <= -2)
2079 {
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)
2087 {
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;
2092
2093 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
2094 {
2095 /* Watch out for 'A ' // x vs. 'A' // x. */
2096
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
2103 {
2104 free (op1_left);
2105 free (op2_left);
2106 if (firstarg)
2107 {
2108 firstarg->expr = op1_right;
2109 secondarg->expr = op2_right;
2110 }
2111 else
2112 {
2113 e->value.op.op1 = op1_right;
2114 e->value.op.op2 = op2_right;
2115 }
2116 optimize_comparison (e, op);
2117 return true;
2118 }
2119 }
2120 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
2121 {
2122 free (op1_right);
2123 free (op2_right);
2124 if (firstarg)
2125 {
2126 firstarg->expr = op1_left;
2127 secondarg->expr = op2_left;
2128 }
2129 else
2130 {
2131 e->value.op.op1 = op1_left;
2132 e->value.op.op2 = op2_left;
2133 }
2134
2135 optimize_comparison (e, op);
2136 return true;
2137 }
2138 }
2139 }
2140 else
2141 {
2142 /* eq can only be -1, 0 or 1 at this point. */
2143 switch (op)
2144 {
2145 case INTRINSIC_EQ:
2146 result = eq == 0;
2147 break;
2148
2149 case INTRINSIC_GE:
2150 result = eq >= 0;
2151 break;
2152
2153 case INTRINSIC_LE:
2154 result = eq <= 0;
2155 break;
2156
2157 case INTRINSIC_NE:
2158 result = eq != 0;
2159 break;
2160
2161 case INTRINSIC_GT:
2162 result = eq > 0;
2163 break;
2164
2165 case INTRINSIC_LT:
2166 result = eq < 0;
2167 break;
2168
2169 default:
2170 gfc_internal_error ("illegal OP in optimize_comparison");
2171 break;
2172 }
2173
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;
2181 }
2182 }
2183
2184 return change;
2185 }
2186
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. */
2190
2191 static bool
2192 optimize_trim (gfc_expr *e)
2193 {
2194 gfc_expr *a;
2195 gfc_ref *ref;
2196 gfc_expr *fcn;
2197 gfc_ref **rr = NULL;
2198
2199 /* Don't do this optimization within an argument list, because
2200 otherwise aliasing issues may occur. */
2201
2202 if (count_arglist != 1)
2203 return false;
2204
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;
2209
2210 a = e->value.function.actual->expr;
2211
2212 if (a->expr_type != EXPR_VARIABLE)
2213 return false;
2214
2215 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
2216
2217 if (a->symtree->n.sym->attr.allocatable)
2218 return false;
2219
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. */
2224
2225 if (a->ref)
2226 {
2227 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
2228 {
2229 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
2230 return false;
2231 }
2232 }
2233
2234 strip_function_call (e);
2235
2236 if (e->ref == NULL)
2237 rr = &(e->ref);
2238
2239 /* Create the reference. */
2240
2241 ref = gfc_get_ref ();
2242 ref->type = REF_SUBSTRING;
2243
2244 /* Set the start of the reference. */
2245
2246 ref->u.ss.start = gfc_get_int_expr (gfc_charlen_int_kind, NULL, 1);
2247
2248 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
2249
2250 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_charlen_int_kind);
2251
2252 /* Set the end of the reference to the call to len_trim. */
2253
2254 ref->u.ss.end = fcn;
2255 gcc_assert (rr != NULL && *rr == NULL);
2256 *rr = ref;
2257 return true;
2258 }
2259
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. */
2263
2264 static void
2265 optimize_minmaxloc (gfc_expr **e)
2266 {
2267 gfc_expr *fn = *e;
2268 gfc_actual_arglist *a;
2269 char *name, *p;
2270
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;
2276
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);
2282
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)
2289 {
2290 a = fn->value.function.actual->next;
2291 gcc_assert (a->expr == NULL);
2292 }
2293 else
2294 {
2295 a = gfc_get_actual_arglist ();
2296 fn->value.function.actual->next = a;
2297 }
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);
2301 }
2302
2303 /* Callback function for code checking that we do not pass a DO variable to an
2304 INTENT(OUT) or INTENT(INOUT) dummy variable. */
2305
2306 static int
2307 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2308 void *data ATTRIBUTE_UNUSED)
2309 {
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;
2317
2318 co = *c;
2319
2320 /* If the doloop_list grew, we have to truncate it here. */
2321
2322 if ((unsigned) doloop_level < doloop_list.length())
2323 doloop_list.truncate (doloop_level);
2324
2325 seen_goto = false;
2326 switch (co->op)
2327 {
2328 case EXEC_DO:
2329
2330 if (co->ext.iterator && co->ext.iterator->var)
2331 loop.c = co;
2332 else
2333 loop.c = NULL;
2334
2335 loop.branch_level = if_level + select_level;
2336 loop.seen_goto = false;
2337 doloop_list.safe_push (loop);
2338 break;
2339
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;
2350
2351 case EXEC_OPEN:
2352 if (co->ext.open->err)
2353 seen_goto = true;
2354 break;
2355
2356 case EXEC_CLOSE:
2357 if (co->ext.close->err)
2358 seen_goto = true;
2359 break;
2360
2361 case EXEC_BACKSPACE:
2362 case EXEC_ENDFILE:
2363 case EXEC_REWIND:
2364 case EXEC_FLUSH:
2365
2366 if (co->ext.filepos->err)
2367 seen_goto = true;
2368 break;
2369
2370 case EXEC_INQUIRE:
2371 if (co->ext.filepos->err)
2372 seen_goto = true;
2373 break;
2374
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;
2380
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;
2385
2386 case EXEC_CALL:
2387
2388 if (co->resolved_sym == NULL)
2389 break;
2390
2391 f = gfc_sym_get_dummy_args (co->resolved_sym);
2392
2393 /* Withot a formal arglist, there is only unknown INTENT,
2394 which we don't check for. */
2395 if (f == NULL)
2396 break;
2397
2398 a = co->ext.actual;
2399
2400 while (a && f)
2401 {
2402 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2403 {
2404 gfc_symbol *do_sym;
2405 cl = lp->c;
2406
2407 if (cl == NULL)
2408 break;
2409
2410 do_sym = cl->ext.iterator->var->symtree->n.sym;
2411
2412 if (a->expr && a->expr->symtree
2413 && a->expr->symtree->n.sym == do_sym)
2414 {
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);
2429 }
2430 }
2431 a = a->next;
2432 f = f->next;
2433 }
2434 break;
2435
2436 default:
2437 break;
2438 }
2439 if (seen_goto && doloop_level > 0)
2440 doloop_list[doloop_level-1].seen_goto = true;
2441
2442 return 0;
2443 }
2444
2445 /* Callback function to warn about different things within DO loops. */
2446
2447 static int
2448 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2449 void *data ATTRIBUTE_UNUSED)
2450 {
2451 do_t *last;
2452
2453 if (doloop_list.length () == 0)
2454 return 0;
2455
2456 if ((*e)->expr_type == EXPR_FUNCTION)
2457 do_intent (e);
2458
2459 last = &doloop_list.last();
2460 if (last->seen_goto && !warn_do_subscript)
2461 return 0;
2462
2463 if ((*e)->expr_type == EXPR_VARIABLE)
2464 do_subscript (e);
2465
2466 return 0;
2467 }
2468
2469 typedef struct
2470 {
2471 gfc_symbol *sym;
2472 mpz_t val;
2473 } insert_index_t;
2474
2475 /* Callback function - if the expression is the variable in data->sym,
2476 replace it with a constant from data->val. */
2477
2478 static int
2479 callback_insert_index (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2480 void *data)
2481 {
2482 insert_index_t *d;
2483 gfc_expr *ex, *n;
2484
2485 ex = (*e);
2486 if (ex->expr_type != EXPR_VARIABLE)
2487 return 0;
2488
2489 d = (insert_index_t *) data;
2490 if (ex->symtree->n.sym != d->sym)
2491 return 0;
2492
2493 n = gfc_get_constant_expr (BT_INTEGER, ex->ts.kind, &ex->where);
2494 mpz_set (n->value.integer, d->val);
2495
2496 gfc_free_expr (ex);
2497 *e = n;
2498 return 0;
2499 }
2500
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. */
2505
2506 static bool
2507 insert_index (gfc_expr *e, gfc_symbol *sym, mpz_t val, mpz_t ret)
2508 {
2509 gfc_expr *n;
2510 insert_index_t data;
2511 bool rc;
2512
2513 if (e->expr_type == EXPR_CONSTANT)
2514 return false;
2515
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);
2520
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 ();
2526
2527 if (n->expr_type == EXPR_CONSTANT)
2528 {
2529 rc = true;
2530 mpz_init_set (ret, n->value.integer);
2531 }
2532 else
2533 rc = false;
2534
2535 mpz_clear (data.val);
2536 gfc_free_expr (n);
2537 return rc;
2538
2539 }
2540
2541 /* Check array subscripts for possible out-of-bounds accesses in DO
2542 loops with constant bounds. */
2543
2544 static int
2545 do_subscript (gfc_expr **e)
2546 {
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;
2553
2554 v = *e;
2555 /* Constants are already checked. */
2556 if (v->expr_type == EXPR_CONSTANT)
2557 return 0;
2558
2559 /* Wrong warnings will be generated in an associate list. */
2560 if (in_assoc_list)
2561 return 0;
2562
2563 /* We already warned about this. */
2564 if (v->do_not_warn)
2565 return 0;
2566
2567 v->do_not_warn = 1;
2568
2569 for (ref = v->ref; ref; ref = ref->next)
2570 {
2571 if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT)
2572 {
2573 ar = & ref->u.ar;
2574 FOR_EACH_VEC_ELT (doloop_list, j, lp)
2575 {
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;
2581
2582 dl = lp->c;
2583 if (dl == NULL)
2584 break;
2585
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;
2592
2593 if (error_not_proven && !warn_do_subscript)
2594 break;
2595
2596 if (error_not_proven)
2597 warn = OPT_Wdo_subscript;
2598 else
2599 warn = 0;
2600
2601 do_sym = dl->ext.iterator->var->symtree->n.sym;
2602 if (do_sym->ts.type != BT_INTEGER)
2603 continue;
2604
2605 /* If we do not know about the stepsize, the loop may be zero trip.
2606 Do not warn in this case. */
2607
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;
2612
2613 if (dl->ext.iterator->start->expr_type == EXPR_CONSTANT)
2614 {
2615 have_do_start = true;
2616 mpz_init_set (do_start, dl->ext.iterator->start->value.integer);
2617 }
2618 else
2619 have_do_start = false;
2620
2621 if (dl->ext.iterator->end->expr_type == EXPR_CONSTANT)
2622 {
2623 have_do_end = true;
2624 mpz_init_set (do_end, dl->ext.iterator->end->value.integer);
2625 }
2626 else
2627 have_do_end = false;
2628
2629 if (!have_do_start && !have_do_end)
2630 return 0;
2631
2632 /* No warning inside a zero-trip loop. */
2633 if (have_do_start && have_do_end)
2634 {
2635 int sgn, cmp;
2636
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;
2641 }
2642
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)
2646 {
2647 mpz_t diff, rem;
2648
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);
2656 }
2657
2658 for (i = 0; i< ar->dimen; i++)
2659 {
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))
2663 {
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);
2672
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);
2681
2682 mpz_clear (val);
2683 }
2684
2685 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_end
2686 && insert_index (ar->start[i], do_sym, do_end, val))
2687 {
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);
2696
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);
2705
2706 mpz_clear (val);
2707 }
2708 }
2709 }
2710 }
2711 }
2712 return 0;
2713 }
2714 /* Function for functions checking that we do not pass a DO variable
2715 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
2716
2717 static int
2718 do_intent (gfc_expr **e)
2719 {
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;
2726
2727 expr = *e;
2728 if (expr->expr_type != EXPR_FUNCTION)
2729 return 0;
2730
2731 /* Intrinsic functions don't modify their arguments. */
2732
2733 if (expr->value.function.isym)
2734 return 0;
2735
2736 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
2737
2738 /* Without a formal arglist, there is only unknown INTENT,
2739 which we don't check for. */
2740 if (f == NULL)
2741 return 0;
2742
2743 a = expr->value.function.actual;
2744
2745 while (a && f)
2746 {
2747 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2748 {
2749 gfc_symbol *do_sym;
2750 dl = lp->c;
2751 if (dl == NULL)
2752 break;
2753
2754 do_sym = dl->ext.iterator->var->symtree->n.sym;
2755
2756 if (a->expr && a->expr->symtree
2757 && a->expr->symtree->n.sym == do_sym)
2758 {
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);
2771 }
2772 }
2773 a = a->next;
2774 f = f->next;
2775 }
2776
2777 return 0;
2778 }
2779
2780 static void
2781 doloop_warn (gfc_namespace *ns)
2782 {
2783 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
2784
2785 for (ns = ns->contained; ns; ns = ns->sibling)
2786 {
2787 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
2788 doloop_warn (ns);
2789 }
2790 }
2791
2792 /* This selction deals with inlining calls to MATMUL. */
2793
2794 /* Replace calls to matmul outside of straight assignments with a temporary
2795 variable so that later inlining will work. */
2796
2797 static int
2798 matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
2799 void *data)
2800 {
2801 gfc_expr *e, *n;
2802 bool *found = (bool *) data;
2803
2804 e = *ep;
2805
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;
2810
2811 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2812 || in_where || in_assoc_list)
2813 return 0;
2814
2815 /* Check if this is already in the form c = matmul(a,b). */
2816
2817 if ((*current_code)->expr2 == e)
2818 return 0;
2819
2820 n = create_var (e, "matmul");
2821
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. */
2825
2826 if (n == NULL)
2827 return 0;
2828
2829 *ep = n;
2830 *found = true;
2831 return 0;
2832 }
2833
2834 /* Set current_code and associated variables so that matmul_to_var_expr can
2835 work. */
2836
2837 static int
2838 matmul_to_var_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2839 void *data ATTRIBUTE_UNUSED)
2840 {
2841 if (current_code != c)
2842 {
2843 current_code = c;
2844 inserted_block = NULL;
2845 changed_statement = NULL;
2846 }
2847
2848 return 0;
2849 }
2850
2851
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. */
2856
2857 static int
2858 matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2859 void *data ATTRIBUTE_UNUSED)
2860 {
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;
2867
2868 co = *c;
2869
2870 if (co->op != EXEC_ASSIGN)
2871 return 0;
2872
2873 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2874 || in_where)
2875 return 0;
2876
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;
2883
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;
2888
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)
2893 {
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;
2898 }
2899 else
2900 a_tmp = true;
2901
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)
2906 {
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;
2911 }
2912 else
2913 b_tmp = true;
2914
2915 if (!a_tmp && !b_tmp)
2916 return 0;
2917
2918 current_code = c;
2919 inserted_block = NULL;
2920 changed_statement = NULL;
2921 if (a_tmp)
2922 {
2923 gfc_expr *at;
2924 at = create_var (a->expr,"mma");
2925 if (at)
2926 a->expr = at;
2927 }
2928 if (b_tmp)
2929 {
2930 gfc_expr *bt;
2931 bt = create_var (b->expr,"mmb");
2932 if (bt)
2933 b->expr = bt;
2934 }
2935 return 0;
2936 }
2937
2938 /* Auxiliary function to build and simplify an array inquiry function.
2939 dim is zero-based. */
2940
2941 static gfc_expr *
2942 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim, int okind = 0)
2943 {
2944 gfc_expr *fcn;
2945 gfc_expr *dim_arg, *kind;
2946 const char *name;
2947 gfc_expr *ec;
2948
2949 switch (id)
2950 {
2951 case GFC_ISYM_LBOUND:
2952 name = "_gfortran_lbound";
2953 break;
2954
2955 case GFC_ISYM_UBOUND:
2956 name = "_gfortran_ubound";
2957 break;
2958
2959 case GFC_ISYM_SIZE:
2960 name = "_gfortran_size";
2961 break;
2962
2963 default:
2964 gcc_unreachable ();
2965 }
2966
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);
2974
2975 ec = gfc_copy_expr (e);
2976
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;
2985 }
2986
2987 /* Builds a logical expression. */
2988
2989 static gfc_expr*
2990 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2991 {
2992 gfc_typespec ts;
2993 gfc_expr *res;
2994
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;
3004
3005 return res;
3006 }
3007
3008
3009 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
3010 compatible typespecs. */
3011
3012 static gfc_expr *
3013 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
3014 {
3015 gfc_expr *res;
3016
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;
3026 }
3027
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. */
3032
3033 static gfc_code *
3034 inline_limit_check (gfc_expr *a, gfc_expr *b, int limit)
3035 {
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;
3041
3042 /* Calculation is done in real to avoid integer overflow. */
3043
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);
3049
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);
3053
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);
3060
3061 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
3062 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
3063
3064 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
3065 gfc_simplify_expr (cond, 0);
3066
3067 else_2 = XCNEW (gfc_code);
3068 else_2->op = EXEC_IF;
3069 else_2->loc = a->where;
3070
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;
3076
3077 if_1 = XCNEW (gfc_code);
3078 if_1->op = EXEC_IF;
3079 if_1->block = if_2;
3080 if_1->loc = a->where;
3081
3082 return if_1;
3083 }
3084
3085
3086 /* Insert code to issue a runtime error if the expressions are not equal. */
3087
3088 static gfc_code *
3089 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
3090 {
3091 gfc_expr *cond;
3092 gfc_code *if_1, *if_2;
3093 gfc_code *c;
3094 gfc_actual_arglist *a1, *a2, *a3;
3095
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;
3101
3102 /* Get a null-terminated message string. */
3103
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;
3108
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;
3113
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;
3118
3119 gfc_check_fe_runtime_error (c->ext.actual);
3120 gfc_resolve_fe_runtime_error (c);
3121
3122 if_2 = XCNEW (gfc_code);
3123 if_2->op = EXEC_IF;
3124 if_2->loc = e1->where;
3125 if_2->next = c;
3126
3127 if_1 = XCNEW (gfc_code);
3128 if_1->op = EXEC_IF;
3129 if_1->block = if_2;
3130 if_1->loc = e1->where;
3131
3132 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
3133 gfc_simplify_expr (cond, 0);
3134 if_2->expr1 = cond;
3135
3136 return if_1;
3137 }
3138
3139 /* Handle matrix reallocation. Caller is responsible to insert into
3140 the code tree.
3141
3142 For the two-dimensional case, build
3143
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
3152
3153 and for the other cases correspondingly.
3154 */
3155
3156 static gfc_code *
3157 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
3158 enum matrix_case m_case)
3159 {
3160
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;
3167
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);
3172
3173 alloc_expr = gfc_copy_expr (c);
3174
3175 ar = gfc_find_array_ref (alloc_expr);
3176 gcc_assert (ar && ar->type == AR_FULL);
3177
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. */
3182
3183 ar->type = AR_ELEMENT;
3184
3185 switch (m_case)
3186 {
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;
3198
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);
3202
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;
3211
3212 case A2TB2:
3213
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);
3216
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;
3225
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;
3232
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;
3239
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);
3245
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));
3252
3253 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3254 break;
3255
3256 default:
3257 gcc_unreachable();
3258
3259 }
3260
3261 gfc_simplify_expr (cond, 0);
3262
3263 /* We need two identical allocate statements in two
3264 branches of the IF statement. */
3265
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);
3271
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;
3277
3278 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
3279 "_gfortran_allocated", c->where,
3280 1, gfc_copy_expr (c));
3281
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;
3288
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;
3294
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;
3299
3300 else_alloc = XCNEW (gfc_code);
3301 else_alloc->op = EXEC_IF;
3302 else_alloc->loc = c->where;
3303 else_alloc->next = allocate_else;
3304
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;
3311
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;
3316
3317 return if_alloc_1;
3318 }
3319
3320 /* Callback function for has_function_or_op. */
3321
3322 static int
3323 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
3324 void *data ATTRIBUTE_UNUSED)
3325 {
3326 if ((*e) == 0)
3327 return 0;
3328 else
3329 return (*e)->expr_type == EXPR_FUNCTION
3330 || (*e)->expr_type == EXPR_OP;
3331 }
3332
3333 /* Returns true if the expression contains a function. */
3334
3335 static bool
3336 has_function_or_op (gfc_expr **e)
3337 {
3338 if (e == NULL)
3339 return false;
3340 else
3341 return gfc_expr_walker (e, is_function_or_op, NULL);
3342 }
3343
3344 /* Freeze (assign to a temporary variable) a single expression. */
3345
3346 static void
3347 freeze_expr (gfc_expr **ep)
3348 {
3349 gfc_expr *ne;
3350 if (has_function_or_op (ep))
3351 {
3352 ne = create_var (*ep, "freeze");
3353 *ep = ne;
3354 }
3355 }
3356
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. */
3360
3361 static void
3362 freeze_references (gfc_expr *e)
3363 {
3364 gfc_ref *r;
3365 gfc_array_ref *ar;
3366 int i;
3367
3368 for (r=e->ref; r; r=r->next)
3369 {
3370 if (r->type == REF_SUBSTRING)
3371 {
3372 if (r->u.ss.start != NULL)
3373 freeze_expr (&r->u.ss.start);
3374
3375 if (r->u.ss.end != NULL)
3376 freeze_expr (&r->u.ss.end);
3377 }
3378 else if (r->type == REF_ARRAY)
3379 {
3380 ar = &r->u.ar;
3381 switch (ar->type)
3382 {
3383 case AR_FULL:
3384 break;
3385
3386 case AR_SECTION:
3387 for (i=0; i<ar->dimen; i++)
3388 {
3389 if (ar->dimen_type[i] == DIMEN_RANGE)
3390 {
3391 freeze_expr (&ar->start[i]);
3392 freeze_expr (&ar->end[i]);
3393 freeze_expr (&ar->stride[i]);
3394 }
3395 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
3396 {
3397 freeze_expr (&ar->start[i]);
3398 }
3399 }
3400 break;
3401
3402 case AR_ELEMENT:
3403 for (i=0; i<ar->dimen; i++)
3404 freeze_expr (&ar->start[i]);
3405 break;
3406
3407 default:
3408 break;
3409 }
3410 }
3411 }
3412 }
3413
3414 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
3415
3416 static gfc_expr *
3417 convert_to_index_kind (gfc_expr *e)
3418 {
3419 gfc_expr *res;
3420
3421 gcc_assert (e != NULL);
3422
3423 res = gfc_copy_expr (e);
3424
3425 gcc_assert (e->ts.type == BT_INTEGER);
3426
3427 if (res->ts.kind != gfc_index_integer_kind)
3428 {
3429 gfc_typespec ts;
3430 gfc_clear_ts (&ts);
3431 ts.type = BT_INTEGER;
3432 ts.kind = gfc_index_integer_kind;
3433
3434 gfc_convert_type_warn (e, &ts, 2, 0);
3435 }
3436
3437 return res;
3438 }
3439
3440 /* Function to create a DO loop including creation of the
3441 iteration variable. gfc_expr are copied.*/
3442
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)
3446 {
3447
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;
3453
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++);
3459
3460
3461 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
3462 gcc_unreachable ();
3463
3464 /* Create the loop variable. */
3465
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);
3474
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;
3481
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);
3495
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;
3502 }
3503
3504 /* Get the upper bound of the DO loops for matmul along a dimension. This
3505 is one-based. */
3506
3507 static gfc_expr*
3508 get_size_m1 (gfc_expr *e, int dimen)
3509 {
3510 mpz_t size;
3511 gfc_expr *res;
3512
3513 if (gfc_array_dimen_size (e, dimen - 1, &size))
3514 {
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);
3519 }
3520 else
3521 {
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);
3527 }
3528
3529 return res;
3530 }
3531
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. */
3538
3539 static gfc_expr*
3540 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
3541 {
3542 gfc_array_ref *ar;
3543 int i;
3544 int rank;
3545 gfc_expr *e;
3546 int i_index;
3547 bool was_fullref;
3548
3549 e = gfc_copy_expr(e_in);
3550
3551 rank = e->rank;
3552
3553 ar = gfc_find_array_ref (e);
3554
3555 /* We scalarize count_index variables, reducing the rank by count_index. */
3556
3557 e->rank = rank - count_index;
3558
3559 was_fullref = ar->type == AR_FULL;
3560
3561 if (e->rank == 0)
3562 ar->type = AR_ELEMENT;
3563 else
3564 ar->type = AR_SECTION;
3565
3566 /* Loop over the indices. For each index, create the expression
3567 index * stride + lbound(e, dim). */
3568
3569 i_index = 0;
3570 for (i=0; i < ar->dimen; i++)
3571 {
3572 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
3573 {
3574 if (index[i_index] != NULL)
3575 {
3576 gfc_expr *lbound, *nindex;
3577 gfc_expr *loopvar;
3578
3579 loopvar = gfc_copy_expr (index[i_index]);
3580
3581 if (ar->stride[i])
3582 {
3583 gfc_expr *tmp;
3584
3585 tmp = gfc_copy_expr(ar->stride[i]);
3586 if (tmp->ts.kind != gfc_index_integer_kind)
3587 {
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);
3593 }
3594 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
3595 }
3596 else
3597 nindex = loopvar;
3598
3599 /* Calculate the lower bound of the expression. */
3600 if (ar->start[i])
3601 {
3602 lbound = gfc_copy_expr (ar->start[i]);
3603 if (lbound->ts.kind != gfc_index_integer_kind)
3604 {
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);
3610
3611 }
3612 }
3613 else
3614 {
3615 gfc_expr *lbound_e;
3616 gfc_ref *ref;
3617
3618 lbound_e = gfc_copy_expr (e_in);
3619
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;
3625
3626 if (ref->next)
3627 {
3628 gfc_free_ref_list (ref->next);
3629 ref->next = NULL;
3630 }
3631
3632 if (!was_fullref)
3633 {
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;
3639
3640 ar = &ref->u.ar;
3641
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. */
3645
3646 if (ar->as->type == AS_ASSUMED_SIZE)
3647 {
3648 ar->type = AR_SECTION;
3649 to = ar->dimen - 1;
3650 }
3651 else
3652 {
3653 to = ar->dimen;
3654 ar->type = AR_FULL;
3655 }
3656
3657 for (j = 0; j < to; j++)
3658 {
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;
3665 }
3666
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. */
3670
3671 if (lbound_e->shape)
3672 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
3673
3674 lbound_e->rank = ar->dimen;
3675 gfc_resolve_expr (lbound_e);
3676 }
3677 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
3678 i + 1);
3679 gfc_free_expr (lbound_e);
3680 }
3681
3682 ar->dimen_type[i] = DIMEN_ELEMENT;
3683
3684 gfc_free_expr (ar->start[i]);
3685 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
3686
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);
3692 }
3693 else if (was_fullref)
3694 {
3695 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
3696 }
3697 i_index ++;
3698 }
3699 }
3700
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;
3705 }
3706
3707 /* Helper function to check for a dimen vector as subscript. */
3708
3709 bool
3710 gfc_has_dimen_vector_ref (gfc_expr *e)
3711 {
3712 gfc_array_ref *ar;
3713 int i;
3714
3715 ar = gfc_find_array_ref (e);
3716 gcc_assert (ar);
3717 if (ar->type == AR_FULL)
3718 return false;
3719
3720 for (i=0; i<ar->dimen; i++)
3721 if (ar->dimen_type[i] == DIMEN_VECTOR)
3722 return true;
3723
3724 return false;
3725 }
3726
3727 /* If handed an expression of the form
3728
3729 TRANSPOSE(CONJG(A))
3730
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. */
3734
3735 static gfc_expr*
3736 check_conjg_transpose_variable (gfc_expr *e, bool *conjg, bool *transpose)
3737 {
3738 *conjg = false;
3739 *transpose = false;
3740
3741 do
3742 {
3743 if (e->expr_type == EXPR_VARIABLE)
3744 {
3745 gcc_assert (e->rank == 1 || e->rank == 2);
3746 return e;
3747 }
3748 else if (e->expr_type == EXPR_FUNCTION)
3749 {
3750 if (e->value.function.isym == NULL)
3751 return NULL;
3752
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;
3758 }
3759 else
3760 return NULL;
3761
3762 e = e->value.function.actual->expr;
3763 }
3764 while(1);
3765
3766 return NULL;
3767 }
3768
3769 /* Macros for unified error messages. */
3770
3771 #define B_ERROR_1 _("Incorrect extent in argument B in MATMUL intrinsic in " \
3772 "dimension 1: is %ld, should be %ld")
3773
3774 #define C_ERROR_1 _("Array bound mismatch for dimension 1 of array " \
3775 "(%ld/%ld)")
3776
3777 #define C_ERROR_2 _("Array bound mismatch for dimension 2 of array " \
3778 "(%ld/%ld)")
3779
3780
3781 /* Inline assignments of the form c = matmul(a,b).
3782 Handle only the cases currently where b and c are rank-two arrays.
3783
3784 This basically translates the code to
3785
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
3800
3801 */
3802
3803 static int
3804 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
3805 void *data ATTRIBUTE_UNUSED)
3806 {
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;
3827
3828 if (co->op != EXEC_ASSIGN)
3829 return 0;
3830
3831 if (in_where || in_assoc_list)
3832 return 0;
3833
3834 /* The BLOCKS generated for the temporary variables and FORALL don't
3835 mix. */
3836 if (forall_level > 0)
3837 return 0;
3838
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;
3844
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;
3851
3852 current_code = c;
3853 inserted_block = NULL;
3854 changed_statement = NULL;
3855
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;
3860
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;
3865
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;
3869
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;
3874
3875 m_case = none;
3876 if (matrix_a->rank == 2)
3877 {
3878 if (transpose_a)
3879 {
3880 if (matrix_b->rank == 2 && !transpose_b)
3881 m_case = A2TB2;
3882 }
3883 else
3884 {
3885 if (matrix_b->rank == 1)
3886 m_case = A2B1;
3887 else /* matrix_b->rank == 2 */
3888 {
3889 if (transpose_b)
3890 m_case = A2B2T;
3891 else
3892 m_case = A2B2;
3893 }
3894 }
3895 }
3896 else /* matrix_a->rank == 1 */
3897 {
3898 if (matrix_b->rank == 2)
3899 {
3900 if (!transpose_b)
3901 m_case = A1B2;
3902 }
3903 }
3904
3905 if (m_case == none)
3906 return 0;
3907
3908 ns = insert_block ();
3909
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. */
3913
3914 switch(expr1->ts.type)
3915 {
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;
3921
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,
3926 0);
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;
3935
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;
3942
3943 break;
3944
3945 default:
3946 gcc_unreachable();
3947 }
3948
3949 current_code = &ns->code;
3950
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);
3957
3958 if (n_vars == 0)
3959 next_code_point = current_code;
3960 else
3961 {
3962 next_code_point = &ns->code;
3963 for (i=0; i<n_vars; i++)
3964 next_code_point = &(*next_code_point)->next;
3965 }
3966
3967 /* Take care of the inline flag. If the limit check evaluates to a
3968 constant, dead code elimination will eliminate the unneeded branch. */
3969
3970 if (flag_inline_matmul_limit > 0 && matrix_a->rank == 2
3971 && matrix_b->rank == 2)
3972 {
3973 if_limit = inline_limit_check (matrix_a, matrix_b,
3974 flag_inline_matmul_limit);
3975
3976 /* Insert the original statement into the else branch. */
3977 if_limit->block->block->next = co;
3978 co->next = NULL;
3979
3980 /* ... and the new ones go into the original one. */
3981 *next_code_point = if_limit;
3982 next_code_point = &if_limit->block->next;
3983 }
3984
3985 zero_e->no_bounds_check = 1;
3986
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;
3993
3994 realloc_c = flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1);
3995
3996 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3997 {
3998 gfc_code *test;
3999 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
4000
4001 switch (m_case)
4002 {
4003 case A2B1:
4004
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;
4010
4011 if (!realloc_c)
4012 {
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;
4018 }
4019 break;
4020
4021 case A1B2:
4022
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;
4028
4029 if (!realloc_c)
4030 {
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;
4036 }
4037 break;
4038
4039 case A2B2:
4040
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;
4046
4047 if (!realloc_c)
4048 {
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;
4054
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;
4060 }
4061 break;
4062
4063 case A2B2T:
4064
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;
4071
4072 if (!realloc_c)
4073 {
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;
4079
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;
4085 }
4086 break;
4087
4088 case A2TB2:
4089
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;
4095
4096 if (!realloc_c)
4097 {
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;
4103
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;
4109 }
4110 break;
4111
4112 default:
4113 gcc_unreachable ();
4114 }
4115 }
4116
4117 /* Handle the reallocation, if needed. */
4118
4119 if (realloc_c)
4120 {
4121 gfc_code *lhs_alloc;
4122
4123 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
4124
4125 *next_code_point = lhs_alloc;
4126 next_code_point = &lhs_alloc->next;
4127
4128 }
4129
4130 *next_code_point = assign_zero;
4131
4132 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
4133
4134 assign_matmul = XCNEW (gfc_code);
4135 assign_matmul->op = EXEC_ASSIGN;
4136 assign_matmul->loc = co->loc;
4137
4138 /* Get the bounds for the loops, create them and create the scalarized
4139 expressions. */
4140
4141 switch (m_case)
4142 {
4143 case A2B2:
4144
4145 u1 = get_size_m1 (matrix_b, 2);
4146 u2 = get_size_m1 (matrix_a, 2);
4147 u3 = get_size_m1 (matrix_a, 1);
4148
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);
4152
4153 do_1->block->next = do_2;
4154 do_2->block->next = do_3;
4155 do_3->block->next = assign_matmul;
4156
4157 var_1 = do_1->ext.iterator->var;
4158 var_2 = do_2->ext.iterator->var;
4159 var_3 = do_3->ext.iterator->var;
4160
4161 list[0] = var_3;
4162 list[1] = var_1;
4163 cscalar = scalarized_expr (co->expr1, list, 2);
4164
4165 list[0] = var_3;
4166 list[1] = var_2;
4167 ascalar = scalarized_expr (matrix_a, list, 2);
4168
4169 list[0] = var_2;
4170 list[1] = var_1;
4171 bscalar = scalarized_expr (matrix_b, list, 2);
4172
4173 break;
4174
4175 case A2B2T:
4176
4177 u1 = get_size_m1 (matrix_b, 1);
4178 u2 = get_size_m1 (matrix_a, 2);
4179 u3 = get_size_m1 (matrix_a, 1);
4180
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);
4184
4185 do_1->block->next = do_2;
4186 do_2->block->next = do_3;
4187 do_3->block->next = assign_matmul;
4188
4189 var_1 = do_1->ext.iterator->var;
4190 var_2 = do_2->ext.iterator->var;
4191 var_3 = do_3->ext.iterator->var;
4192
4193 list[0] = var_3;
4194 list[1] = var_1;
4195 cscalar = scalarized_expr (co->expr1, list, 2);
4196
4197 list[0] = var_3;
4198 list[1] = var_2;
4199 ascalar = scalarized_expr (matrix_a, list, 2);
4200
4201 list[0] = var_1;
4202 list[1] = var_2;
4203 bscalar = scalarized_expr (matrix_b, list, 2);
4204
4205 break;
4206
4207 case A2TB2:
4208
4209 u1 = get_size_m1 (matrix_a, 2);
4210 u2 = get_size_m1 (matrix_b, 2);
4211 u3 = get_size_m1 (matrix_a, 1);
4212
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);
4216
4217 do_1->block->next = do_2;
4218 do_2->block->next = do_3;
4219 do_3->block->next = assign_matmul;
4220
4221 var_1 = do_1->ext.iterator->var;
4222 var_2 = do_2->ext.iterator->var;
4223 var_3 = do_3->ext.iterator->var;
4224
4225 list[0] = var_1;
4226 list[1] = var_2;
4227 cscalar = scalarized_expr (co->expr1, list, 2);
4228
4229 list[0] = var_3;
4230 list[1] = var_1;
4231 ascalar = scalarized_expr (matrix_a, list, 2);
4232
4233 list[0] = var_3;
4234 list[1] = var_2;
4235 bscalar = scalarized_expr (matrix_b, list, 2);
4236
4237 break;
4238
4239 case A2B1:
4240 u1 = get_size_m1 (matrix_b, 1);
4241 u2 = get_size_m1 (matrix_a, 1);
4242
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);
4245
4246 do_1->block->next = do_2;
4247 do_2->block->next = assign_matmul;
4248
4249 var_1 = do_1->ext.iterator->var;
4250 var_2 = do_2->ext.iterator->var;
4251
4252 list[0] = var_2;
4253 cscalar = scalarized_expr (co->expr1, list, 1);
4254
4255 list[0] = var_2;
4256 list[1] = var_1;
4257 ascalar = scalarized_expr (matrix_a, list, 2);
4258
4259 list[0] = var_1;
4260 bscalar = scalarized_expr (matrix_b, list, 1);
4261
4262 break;
4263
4264 case A1B2:
4265 u1 = get_size_m1 (matrix_b, 2);
4266 u2 = get_size_m1 (matrix_a, 1);
4267
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);
4270
4271 do_1->block->next = do_2;
4272 do_2->block->next = assign_matmul;
4273
4274 var_1 = do_1->ext.iterator->var;
4275 var_2 = do_2->ext.iterator->var;
4276
4277 list[0] = var_1;
4278 cscalar = scalarized_expr (co->expr1, list, 1);
4279
4280 list[0] = var_2;
4281 ascalar = scalarized_expr (matrix_a, list, 1);
4282
4283 list[0] = var_2;
4284 list[1] = var_1;
4285 bscalar = scalarized_expr (matrix_b, list, 2);
4286
4287 break;
4288
4289 default:
4290 gcc_unreachable();
4291 }
4292
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)
4296 {
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;
4302 }
4303
4304 if (conjg_b)
4305 {
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;
4311 }
4312 /* First loop comes after the zero assignment. */
4313 assign_zero->next = do_1;
4314
4315 /* Build the assignment expression in the loop. */
4316 assign_matmul->expr1 = gfc_copy_expr (cscalar);
4317
4318 mult = get_operand (op_times, ascalar, bscalar);
4319 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
4320
4321 /* If we don't want to keep the original statement around in
4322 the else branch, we can free it. */
4323
4324 if (if_limit == NULL)
4325 gfc_free_statements(co);
4326 else
4327 co->next = NULL;
4328
4329 gfc_free_expr (zero);
4330 *walk_subtrees = 0;
4331 return 0;
4332 }
4333
4334 /* Change matmul function calls in the form of
4335
4336 c = matmul(a,b)
4337
4338 to the corresponding call to a BLAS routine, if applicable. */
4339
4340 static int
4341 call_external_blas (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
4342 void *data ATTRIBUTE_UNUSED)
4343 {
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;
4360
4361 /* Many of the tests for inline matmul also apply here. */
4362
4363 co = *c;
4364
4365 if (co->op != EXEC_ASSIGN)
4366 return 0;
4367
4368 if (in_where || in_assoc_list)
4369 return 0;
4370
4371 /* The BLOCKS generated for the temporary variables and FORALL don't
4372 mix. */
4373 if (forall_level > 0)
4374 return 0;
4375
4376 /* For now don't do anything in OpenMP workshare, it confuses
4377 its translation, which expects only the allowed statements in there. */
4378
4379 if (in_omp_workshare)
4380 return 0;
4381
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;
4388
4389 type = expr2->ts.type;
4390 kind = expr2->ts.kind;
4391
4392 /* Guard against recursion. */
4393
4394 if (expr2->external_blas)
4395 return 0;
4396
4397 if (type != expr1->ts.type || kind != expr1->ts.kind)
4398 return 0;
4399
4400 if (type == BT_REAL)
4401 {
4402 if (kind == 4)
4403 blas_name = "sgemm";
4404 else if (kind == 8)
4405 blas_name = "dgemm";
4406 else
4407 return 0;
4408 }
4409 else if (type == BT_COMPLEX)
4410 {
4411 if (kind == 4)
4412 blas_name = "cgemm";
4413 else if (kind == 8)
4414 blas_name = "zgemm";
4415 else
4416 return 0;
4417 }
4418 else
4419 return 0;
4420
4421 a = expr2->value.function.actual;
4422 if (a->expr->rank != 2)
4423 return 0;
4424
4425 b = a->next;
4426 if (b->expr->rank != 2)
4427 return 0;
4428
4429 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
4430 if (matrix_a == NULL)
4431 return 0;
4432
4433 if (transpose_a)
4434 {
4435 if (conjg_a)
4436 transa = "C";
4437 else
4438 transa = "T";
4439 }
4440 else
4441 transa = "N";
4442
4443 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
4444 if (matrix_b == NULL)
4445 return 0;
4446
4447 if (transpose_b)
4448 {
4449 if (conjg_b)
4450 transb = "C";
4451 else
4452 transb = "T";
4453 }
4454 else
4455 transb = "N";
4456
4457 if (transpose_a)
4458 {
4459 if (transpose_b)
4460 m_case = A2TB2T;
4461 else
4462 m_case = A2TB2;
4463 }
4464 else
4465 {
4466 if (transpose_b)
4467 m_case = A2B2T;
4468 else
4469 m_case = A2B2;
4470 }
4471
4472 current_code = c;
4473 inserted_block = NULL;
4474 changed_statement = NULL;
4475
4476 expr2->external_blas = 1;
4477
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;
4482
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;
4489
4490 call = XCNEW (gfc_code);
4491 call->loc = co->loc;
4492
4493 /* Bounds checking - a bit simpler than for inlining since we only
4494 have to take care of two-dimensional arrays here. */
4495
4496 realloc_c = flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1);
4497 next_code_point = &(if_limit->block->block->next);
4498
4499 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
4500 {
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)
4505 {
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;
4512
4513 if (!realloc_c)
4514 {
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;
4520
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;
4526 }
4527 break;
4528
4529 case A2B2T:
4530
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;
4537
4538 if (!realloc_c)
4539 {
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;
4545
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;
4551 }
4552 break;
4553
4554 case A2TB2:
4555
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;
4561
4562 if (!realloc_c)
4563 {
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;
4569
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;
4575 }
4576 break;
4577
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;
4584
4585 if (!realloc_c)
4586 {
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;
4592
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;
4598 }
4599 break;
4600
4601 default:
4602 gcc_unreachable ();
4603 }
4604 }
4605
4606 /* Handle the reallocation, if needed. */
4607
4608 if (realloc_c)
4609 {
4610 gfc_code *lhs_alloc;
4611
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;
4615 }
4616
4617 *next_code_point = call;
4618 if_limit->next = co_next;
4619
4620 /* Set up the BLAS call. */
4621
4622 call->op = EXEC_CALL;
4623
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;
4629
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);
4634
4635 call->ext.actual = next;
4636
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;
4643
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);
4648
4649 b1 = get_array_inq_function (GFC_ISYM_SIZE, gfc_copy_expr (b->expr), 1,
4650 gfc_integer_4_kind);
4651
4652 /* Argument M. */
4653 actual = next;
4654 next = gfc_get_actual_arglist ();
4655 next->expr = c1;
4656 actual->next = next;
4657
4658 /* Argument N. */
4659 actual = next;
4660 next = gfc_get_actual_arglist ();
4661 next->expr = c2;
4662 actual->next = next;
4663
4664 /* Argument K. */
4665 actual = next;
4666 next = gfc_get_actual_arglist ();
4667 next->expr = b1;
4668 actual->next = next;
4669
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;
4679
4680 /* Argument A. */
4681 actual = next;
4682 next = gfc_get_actual_arglist ();
4683 next->expr = gfc_copy_expr (matrix_a);
4684 actual->next = next;
4685
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;
4692
4693 /* Argument B. */
4694 actual = next;
4695 next = gfc_get_actual_arglist ();
4696 next->expr = gfc_copy_expr (matrix_b);
4697 actual->next = next;
4698
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;
4705
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;
4715
4716 /* Argument C. */
4717
4718 actual = next;
4719 next = gfc_get_actual_arglist ();
4720 next->expr = gfc_copy_expr (expr1);
4721 actual->next = next;
4722
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;
4729
4730 return 0;
4731 }
4732
4733
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.
4737
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.
4741
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. */
4746
4747 /* Type for holding index information. */
4748
4749 typedef struct {
4750 gfc_symbol *sym;
4751 gfc_forall_iterator *fa;
4752 int num;
4753 int n[GFC_MAX_DIMENSIONS];
4754 } ind_type;
4755
4756 /* Callback function to determine if an expression is the
4757 corresponding variable. */
4758
4759 static int
4760 has_var (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
4761 {
4762 gfc_expr *expr = *e;
4763 gfc_symbol *sym;
4764
4765 if (expr->expr_type != EXPR_VARIABLE)
4766 return 0;
4767
4768 sym = (gfc_symbol *) data;
4769 return sym == expr->symtree->n.sym;
4770 }
4771
4772 /* Callback function to calculate the cost of a certain index. */
4773
4774 static int
4775 index_cost (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
4776 void *data)
4777 {
4778 ind_type *ind;
4779 gfc_expr *expr;
4780 gfc_array_ref *ar;
4781 gfc_ref *ref;
4782 int i,j;
4783
4784 expr = *e;
4785 if (expr->expr_type != EXPR_VARIABLE)
4786 return 0;
4787
4788 ar = NULL;
4789 for (ref = expr->ref; ref; ref = ref->next)
4790 {
4791 if (ref->type == REF_ARRAY)
4792 {
4793 ar = &ref->u.ar;
4794 break;
4795 }
4796 }
4797 if (ar == NULL || ar->type != AR_ELEMENT)
4798 return 0;
4799
4800 ind = (ind_type *) data;
4801 for (i = 0; i < ar->dimen; i++)
4802 {
4803 for (j=0; ind[j].sym != NULL; j++)
4804 {
4805 if (gfc_expr_walker (&ar->start[i], has_var, (void *) (ind[j].sym)))
4806 ind[j].n[i]++;
4807 }
4808 }
4809 return 0;
4810 }
4811
4812 /* Callback function for qsort, to sort the loop indices. */
4813
4814 static int
4815 loop_comp (const void *e1, const void *e2)
4816 {
4817 const ind_type *i1 = (const ind_type *) e1;
4818 const ind_type *i2 = (const ind_type *) e2;
4819 int i;
4820
4821 for (i=GFC_MAX_DIMENSIONS-1; i >= 0; i--)
4822 {
4823 if (i1->n[i] != i2->n[i])
4824 return i1->n[i] - i2->n[i];
4825 }
4826 /* All other things being equal, let's not change the ordering. */
4827 return i2->num - i1->num;
4828 }
4829
4830 /* Main function to do the index interchange. */
4831
4832 static int
4833 index_interchange (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
4834 void *data ATTRIBUTE_UNUSED)
4835 {
4836 gfc_code *co;
4837 co = *c;
4838 int n_iter;
4839 gfc_forall_iterator *fa;
4840 ind_type *ind;
4841 int i, j;
4842
4843 if (co->op != EXEC_FORALL && co->op != EXEC_DO_CONCURRENT)
4844 return 0;
4845
4846 n_iter = 0;
4847 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4848 n_iter ++;
4849
4850 /* Nothing to reorder. */
4851 if (n_iter < 2)
4852 return 0;
4853
4854 ind = XALLOCAVEC (ind_type, n_iter + 1);
4855
4856 i = 0;
4857 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4858 {
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++;
4865 }
4866 ind[n_iter].sym = NULL;
4867 ind[n_iter].fa = NULL;
4868
4869 gfc_code_walker (c, gfc_dummy_code_callback, index_cost, (void *) ind);
4870 qsort ((void *) ind, n_iter, sizeof (ind_type), loop_comp);
4871
4872 /* Do the actual index interchange. */
4873 co->ext.forall_iterator = fa = ind[0].fa;
4874 for (i=1; i<n_iter; i++)
4875 {
4876 fa->next = ind[i].fa;
4877 fa = fa->next;
4878 }
4879 fa->next = NULL;
4880
4881 if (flag_warn_frontend_loop_interchange)
4882 {
4883 for (i=1; i<n_iter; i++)
4884 {
4885 if (ind[i-1].num > ind[i].num)
4886 {
4887 gfc_warning (OPT_Wfrontend_loop_interchange,
4888 "Interchanging loops at %L", &co->loc);
4889 break;
4890 }
4891 }
4892 }
4893
4894 return 0;
4895 }
4896
4897 #define WALK_SUBEXPR(NODE) \
4898 do \
4899 { \
4900 result = gfc_expr_walker (&(NODE), exprfn, data); \
4901 if (result) \
4902 return result; \
4903 } \
4904 while (0)
4905 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
4906
4907 /* Walk expression *E, calling EXPRFN on each expression in it. */
4908
4909 int
4910 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
4911 {
4912 while (*e)
4913 {
4914 int walk_subtrees = 1;
4915 gfc_actual_arglist *a;
4916 gfc_ref *r;
4917 gfc_constructor *c;
4918
4919 int result = exprfn (e, &walk_subtrees, data);
4920 if (result)
4921 return result;
4922 if (walk_subtrees)
4923 switch ((*e)->expr_type)
4924 {
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;
4939
4940 case EXPR_STRUCTURE:
4941 case EXPR_ARRAY:
4942 for (c = gfc_constructor_first ((*e)->value.constructor); c;
4943 c = gfc_constructor_next (c))
4944 {
4945 if (c->iterator == NULL)
4946 WALK_SUBEXPR (c->expr);
4947 else
4948 {
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);
4956 }
4957 }
4958
4959 if ((*e)->expr_type != EXPR_ARRAY)
4960 break;
4961
4962 /* Fall through to the variable case in order to walk the
4963 reference. */
4964 gcc_fallthrough ();
4965
4966 case EXPR_SUBSTRING:
4967 case EXPR_VARIABLE:
4968 for (r = (*e)->ref; r; r = r->next)
4969 {
4970 gfc_array_ref *ar;
4971 int i;
4972
4973 switch (r->type)
4974 {
4975 case REF_ARRAY:
4976 ar = &r->u.ar;
4977 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
4978 {
4979 for (i=0; i< ar->dimen; i++)
4980 {
4981 WALK_SUBEXPR (ar->start[i]);
4982 WALK_SUBEXPR (ar->end[i]);
4983 WALK_SUBEXPR (ar->stride[i]);
4984 }
4985 }
4986
4987 break;
4988
4989 case REF_SUBSTRING:
4990 WALK_SUBEXPR (r->u.ss.start);
4991 WALK_SUBEXPR (r->u.ss.end);
4992 break;
4993
4994 case REF_COMPONENT:
4995 case REF_INQUIRY:
4996 break;
4997 }
4998 }
4999
5000 default:
5001 break;
5002 }
5003 return 0;
5004 }
5005 return 0;
5006 }
5007
5008 #define WALK_SUBCODE(NODE) \
5009 do \
5010 { \
5011 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
5012 if (result) \
5013 return result; \
5014 } \
5015 while (0)
5016
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. */
5021
5022 int
5023 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
5024 void *data)
5025 {
5026 for (; *c; c = &(*c)->next)
5027 {
5028 int walk_subtrees = 1;
5029 int result = codefn (c, &walk_subtrees, data);
5030 if (result)
5031 return result;
5032
5033 if (walk_subtrees)
5034 {
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;
5041
5042 /* There might be statement insertions before the current code,
5043 which must not affect the expression walker. */
5044
5045 co = *c;
5046 saved_in_omp_workshare = in_omp_workshare;
5047 saved_in_where = in_where;
5048
5049 switch (co->op)
5050 {
5051
5052 case EXEC_BLOCK:
5053 WALK_SUBCODE (co->ext.block.ns->code);
5054 if (co->ext.block.assoc)
5055 {
5056 bool saved_in_assoc_list = in_assoc_list;
5057
5058 in_assoc_list = true;
5059 for (alist = co->ext.block.assoc; alist; alist = alist->next)
5060 WALK_SUBEXPR (alist->target);
5061
5062 in_assoc_list = saved_in_assoc_list;
5063 }
5064
5065 break;
5066
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;
5074
5075 case EXEC_IF:
5076 if_level ++;
5077 break;
5078
5079 case EXEC_WHERE:
5080 in_where = true;
5081 break;
5082
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;
5088
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;
5094
5095 case EXEC_SELECT:
5096 WALK_SUBEXPR (co->expr1);
5097 select_level ++;
5098 for (b = co->block; b; b = b->block)
5099 {
5100 gfc_case *cp;
5101 for (cp = b->ext.block.case_list; cp; cp = cp->next)
5102 {
5103 WALK_SUBEXPR (cp->low);
5104 WALK_SUBEXPR (cp->high);
5105 }
5106 WALK_SUBCODE (b->next);
5107 }
5108 continue;
5109
5110 case EXEC_ALLOCATE:
5111 case EXEC_DEALLOCATE:
5112 {
5113 gfc_alloc *a;
5114 for (a = co->ext.alloc.list; a; a = a->next)
5115 WALK_SUBEXPR (a->expr);
5116 break;
5117 }
5118
5119 case EXEC_FORALL:
5120 case EXEC_DO_CONCURRENT:
5121 {
5122 gfc_forall_iterator *fa;
5123 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
5124 {
5125 WALK_SUBEXPR (fa->var);
5126 WALK_SUBEXPR (fa->start);
5127 WALK_SUBEXPR (fa->end);
5128 WALK_SUBEXPR (fa->stride);
5129 }
5130 if (co->op == EXEC_FORALL)
5131 forall_level ++;
5132 break;
5133 }
5134
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;
5160
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;
5167
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;
5176
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;
5215
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;
5222
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;
5243
5244 case EXEC_OMP_PARALLEL:
5245 case EXEC_OMP_PARALLEL_DO:
5246 case EXEC_OMP_PARALLEL_DO_SIMD:
5247 case EXEC_OMP_PARALLEL_SECTIONS:
5248
5249 in_omp_workshare = false;
5250
5251 /* This goto serves as a shortcut to avoid code
5252 duplication or a larger if or switch statement. */
5253 goto check_omp_clauses;
5254
5255 case EXEC_OMP_WORKSHARE:
5256 case EXEC_OMP_PARALLEL_WORKSHARE:
5257
5258 in_omp_workshare = true;
5259
5260 /* Fall through */
5261
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:
5296
5297 /* Come to this label only from the
5298 EXEC_OMP_PARALLEL_* cases above. */
5299
5300 check_omp_clauses:
5301
5302 if (co->ext.omp_clauses)
5303 {
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);
5331 }
5332 break;
5333 default:
5334 break;
5335 }
5336
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)
5342 {
5343 WALK_SUBEXPR (b->expr1);
5344 WALK_SUBEXPR (b->expr2);
5345 WALK_SUBCODE (b->next);
5346 }
5347
5348 if (co->op == EXEC_FORALL)
5349 forall_level --;
5350
5351 if (co->op == EXEC_DO)
5352 doloop_level --;
5353
5354 if (co->op == EXEC_IF)
5355 if_level --;
5356
5357 if (co->op == EXEC_SELECT)
5358 select_level --;
5359
5360 in_omp_workshare = saved_in_omp_workshare;
5361 in_where = saved_in_where;
5362 }
5363 }
5364 return 0;
5365 }
5366
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. */
5371
5372
5373 /* Common tests for argument checking for both functions and subroutines. */
5374
5375 static int
5376 check_externals_procedure (gfc_symbol *sym, locus *loc,
5377 gfc_actual_arglist *actual)
5378 {
5379 gfc_gsymbol *gsym;
5380 gfc_symbol *def_sym = NULL;
5381
5382 if (sym == NULL || sym->attr.is_bind_c)
5383 return 0;
5384
5385 if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN)
5386 return 0;
5387
5388 if (sym->attr.if_source == IFSRC_IFBODY || sym->attr.if_source == IFSRC_DECL)
5389 return 0;
5390
5391 gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
5392 if (gsym == NULL)
5393 return 0;
5394
5395 if (gsym->ns)
5396 gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym);
5397
5398 if (def_sym)
5399 {
5400 gfc_compare_actual_formal (&actual, def_sym->formal, 0, 0, 0, loc);
5401 return 0;
5402 }
5403
5404 /* First time we have seen this procedure called. Let's create an
5405 "interface" from the call and put it into a new namespace. */
5406 gfc_namespace *save_ns;
5407 gfc_symbol *new_sym;
5408
5409 gsym->where = *loc;
5410 save_ns = gfc_current_ns;
5411 gsym->ns = gfc_get_namespace (gfc_current_ns, 0);
5412 gsym->ns->proc_name = sym;
5413
5414 gfc_get_symbol (sym->name, gsym->ns, &new_sym);
5415 gcc_assert (new_sym);
5416 new_sym->attr = sym->attr;
5417 new_sym->attr.if_source = IFSRC_DECL;
5418 gfc_current_ns = gsym->ns;
5419
5420 gfc_get_formal_from_actual_arglist (new_sym, actual);
5421 gfc_current_ns = save_ns;
5422
5423 return 0;
5424
5425 }
5426
5427 /* Callback for calls of external routines. */
5428
5429 static int
5430 check_externals_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
5431 void *data ATTRIBUTE_UNUSED)
5432 {
5433 gfc_code *co = *c;
5434 gfc_symbol *sym;
5435 locus *loc;
5436 gfc_actual_arglist *actual;
5437
5438 if (co->op != EXEC_CALL)
5439 return 0;
5440
5441 sym = co->resolved_sym;
5442 loc = &co->loc;
5443 actual = co->ext.actual;
5444
5445 return check_externals_procedure (sym, loc, actual);
5446
5447 }
5448
5449 /* Callback for external functions. */
5450
5451 static int
5452 check_externals_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
5453 void *data ATTRIBUTE_UNUSED)
5454 {
5455 gfc_expr *e = *ep;
5456 gfc_symbol *sym;
5457 locus *loc;
5458 gfc_actual_arglist *actual;
5459
5460 if (e->expr_type != EXPR_FUNCTION)
5461 return 0;
5462
5463 sym = e->value.function.esym;
5464 if (sym == NULL)
5465 return 0;
5466
5467 loc = &e->where;
5468 actual = e->value.function.actual;
5469
5470 return check_externals_procedure (sym, loc, actual);
5471 }
5472
5473 /* Called routine. */
5474
5475 void
5476 gfc_check_externals (gfc_namespace *ns)
5477 {
5478
5479 gfc_clear_error ();
5480
5481 /* Turn errors into warnings if the user indicated this. */
5482
5483 if (!pedantic && flag_allow_argument_mismatch)
5484 gfc_errors_to_warnings (true);
5485
5486 gfc_code_walker (&ns->code, check_externals_code, check_externals_expr, NULL);
5487
5488 for (ns = ns->contained; ns; ns = ns->sibling)
5489 {
5490 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
5491 gfc_check_externals (ns);
5492 }
5493
5494 gfc_errors_to_warnings (false);
5495 }