]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/fortran/frontend-passes.c
re PR fortran/85387 (incorrect output with optimization /= 0)
[thirdparty/gcc.git] / gcc / fortran / frontend-passes.c
1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2018 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 bool has_dimen_vector_ref (gfc_expr *);
57 static int matmul_temp_args (gfc_code **, int *,void *data);
58 static int index_interchange (gfc_code **, int*, void *);
59
60 #ifdef CHECKING_P
61 static void check_locus (gfc_namespace *);
62 #endif
63
64 /* How deep we are inside an argument list. */
65
66 static int count_arglist;
67
68 /* Vector of gfc_expr ** we operate on. */
69
70 static vec<gfc_expr **> expr_array;
71
72 /* Pointer to the gfc_code we currently work on - to be able to insert
73 a block before the statement. */
74
75 static gfc_code **current_code;
76
77 /* Pointer to the block to be inserted, and the statement we are
78 changing within the block. */
79
80 static gfc_code *inserted_block, **changed_statement;
81
82 /* The namespace we are currently dealing with. */
83
84 static gfc_namespace *current_ns;
85
86 /* If we are within any forall loop. */
87
88 static int forall_level;
89
90 /* Keep track of whether we are within an OMP workshare. */
91
92 static bool in_omp_workshare;
93
94 /* Keep track of whether we are within a WHERE statement. */
95
96 static bool in_where;
97
98 /* Keep track of iterators for array constructors. */
99
100 static int iterator_level;
101
102 /* Keep track of DO loop levels. */
103
104 typedef struct {
105 gfc_code *c;
106 int branch_level;
107 bool seen_goto;
108 } do_t;
109
110 static vec<do_t> doloop_list;
111 static int doloop_level;
112
113 /* Keep track of if and select case levels. */
114
115 static int if_level;
116 static int select_level;
117
118 /* Vector of gfc_expr * to keep track of DO loops. */
119
120 struct my_struct *evec;
121
122 /* Keep track of association lists. */
123
124 static bool in_assoc_list;
125
126 /* Counter for temporary variables. */
127
128 static int var_num = 1;
129
130 /* What sort of matrix we are dealing with when inlining MATMUL. */
131
132 enum matrix_case { none=0, A2B2, A2B1, A1B2, A2B2T, A2TB2 };
133
134 /* Keep track of the number of expressions we have inserted so far
135 using create_var. */
136
137 int n_vars;
138
139 /* Entry point - run all passes for a namespace. */
140
141 void
142 gfc_run_passes (gfc_namespace *ns)
143 {
144
145 /* Warn about dubious DO loops where the index might
146 change. */
147
148 doloop_level = 0;
149 if_level = 0;
150 select_level = 0;
151 doloop_warn (ns);
152 doloop_list.release ();
153 int w, e;
154
155 #ifdef CHECKING_P
156 check_locus (ns);
157 #endif
158
159 gfc_get_errors (&w, &e);
160 if (e > 0)
161 return;
162
163 if (flag_frontend_optimize || flag_frontend_loop_interchange)
164 optimize_namespace (ns);
165
166 if (flag_frontend_optimize)
167 {
168 optimize_reduction (ns);
169 if (flag_dump_fortran_optimized)
170 gfc_dump_parse_tree (ns, stdout);
171
172 expr_array.release ();
173 }
174
175 if (flag_realloc_lhs)
176 realloc_strings (ns);
177 }
178
179 #ifdef CHECKING_P
180
181 /* Callback function: Warn if there is no location information in a
182 statement. */
183
184 static int
185 check_locus_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
186 void *data ATTRIBUTE_UNUSED)
187 {
188 current_code = c;
189 if (c && *c && (((*c)->loc.nextc == NULL) || ((*c)->loc.lb == NULL)))
190 gfc_warning_internal (0, "No location in statement");
191
192 return 0;
193 }
194
195
196 /* Callback function: Warn if there is no location information in an
197 expression. */
198
199 static int
200 check_locus_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
201 void *data ATTRIBUTE_UNUSED)
202 {
203
204 if (e && *e && (((*e)->where.nextc == NULL || (*e)->where.lb == NULL)))
205 gfc_warning_internal (0, "No location in expression near %L",
206 &((*current_code)->loc));
207 return 0;
208 }
209
210 /* Run check for missing location information. */
211
212 static void
213 check_locus (gfc_namespace *ns)
214 {
215 gfc_code_walker (&ns->code, check_locus_code, check_locus_expr, NULL);
216
217 for (ns = ns->contained; ns; ns = ns->sibling)
218 {
219 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
220 check_locus (ns);
221 }
222 }
223
224 #endif
225
226 /* Callback for each gfc_code node invoked from check_realloc_strings.
227 For an allocatable LHS string which also appears as a variable on
228 the RHS, replace
229
230 a = a(x:y)
231
232 with
233
234 tmp = a(x:y)
235 a = tmp
236 */
237
238 static int
239 realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
240 void *data ATTRIBUTE_UNUSED)
241 {
242 gfc_expr *expr1, *expr2;
243 gfc_code *co = *c;
244 gfc_expr *n;
245 gfc_ref *ref;
246 bool found_substr;
247
248 if (co->op != EXEC_ASSIGN)
249 return 0;
250
251 expr1 = co->expr1;
252 if (expr1->ts.type != BT_CHARACTER
253 || !gfc_expr_attr(expr1).allocatable
254 || !expr1->ts.deferred)
255 return 0;
256
257 expr2 = gfc_discard_nops (co->expr2);
258
259 if (expr2->expr_type == EXPR_VARIABLE)
260 {
261 found_substr = false;
262 for (ref = expr2->ref; ref; ref = ref->next)
263 {
264 if (ref->type == REF_SUBSTRING)
265 {
266 found_substr = true;
267 break;
268 }
269 }
270 if (!found_substr)
271 return 0;
272 }
273 else if (expr2->expr_type != EXPR_ARRAY
274 && (expr2->expr_type != EXPR_OP
275 || expr2->value.op.op != INTRINSIC_CONCAT))
276 return 0;
277
278 if (!gfc_check_dependency (expr1, expr2, true))
279 return 0;
280
281 /* gfc_check_dependency doesn't always pick up identical expressions.
282 However, eliminating the above sends the compiler into an infinite
283 loop on valid expressions. Without this check, the gimplifier emits
284 an ICE for a = a, where a is deferred character length. */
285 if (!gfc_dep_compare_expr (expr1, expr2))
286 return 0;
287
288 current_code = c;
289 inserted_block = NULL;
290 changed_statement = NULL;
291 n = create_var (expr2, "realloc_string");
292 co->expr2 = n;
293 return 0;
294 }
295
296 /* Callback for each gfc_code node invoked through gfc_code_walker
297 from optimize_namespace. */
298
299 static int
300 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
301 void *data ATTRIBUTE_UNUSED)
302 {
303
304 gfc_exec_op op;
305
306 op = (*c)->op;
307
308 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
309 || op == EXEC_CALL_PPC)
310 count_arglist = 1;
311 else
312 count_arglist = 0;
313
314 current_code = c;
315 inserted_block = NULL;
316 changed_statement = NULL;
317
318 if (op == EXEC_ASSIGN)
319 optimize_assignment (*c);
320 return 0;
321 }
322
323 /* Callback for each gfc_expr node invoked through gfc_code_walker
324 from optimize_namespace. */
325
326 static int
327 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
328 void *data ATTRIBUTE_UNUSED)
329 {
330 bool function_expr;
331
332 if ((*e)->expr_type == EXPR_FUNCTION)
333 {
334 count_arglist ++;
335 function_expr = true;
336 }
337 else
338 function_expr = false;
339
340 if (optimize_trim (*e))
341 gfc_simplify_expr (*e, 0);
342
343 if (optimize_lexical_comparison (*e))
344 gfc_simplify_expr (*e, 0);
345
346 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
347 gfc_simplify_expr (*e, 0);
348
349 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
350 switch ((*e)->value.function.isym->id)
351 {
352 case GFC_ISYM_MINLOC:
353 case GFC_ISYM_MAXLOC:
354 optimize_minmaxloc (e);
355 break;
356 default:
357 break;
358 }
359
360 if (function_expr)
361 count_arglist --;
362
363 return 0;
364 }
365
366 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
367 function is a scalar, just copy it; otherwise returns the new element, the
368 old one can be freed. */
369
370 static gfc_expr *
371 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
372 {
373 gfc_expr *fcn, *e = c->expr;
374
375 fcn = gfc_copy_expr (e);
376 if (c->iterator)
377 {
378 gfc_constructor_base newbase;
379 gfc_expr *new_expr;
380 gfc_constructor *new_c;
381
382 newbase = NULL;
383 new_expr = gfc_get_expr ();
384 new_expr->expr_type = EXPR_ARRAY;
385 new_expr->ts = e->ts;
386 new_expr->where = e->where;
387 new_expr->rank = 1;
388 new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
389 new_c->iterator = c->iterator;
390 new_expr->value.constructor = newbase;
391 c->iterator = NULL;
392
393 fcn = new_expr;
394 }
395
396 if (fcn->rank != 0)
397 {
398 gfc_isym_id id = fn->value.function.isym->id;
399
400 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
401 fcn = gfc_build_intrinsic_call (current_ns, id,
402 fn->value.function.isym->name,
403 fn->where, 3, fcn, NULL, NULL);
404 else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
405 fcn = gfc_build_intrinsic_call (current_ns, id,
406 fn->value.function.isym->name,
407 fn->where, 2, fcn, NULL);
408 else
409 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
410
411 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
412 }
413
414 return fcn;
415 }
416
417 /* Callback function for optimzation of reductions to scalars. Transform ANY
418 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
419 correspondingly. Handly only the simple cases without MASK and DIM. */
420
421 static int
422 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
423 void *data ATTRIBUTE_UNUSED)
424 {
425 gfc_expr *fn, *arg;
426 gfc_intrinsic_op op;
427 gfc_isym_id id;
428 gfc_actual_arglist *a;
429 gfc_actual_arglist *dim;
430 gfc_constructor *c;
431 gfc_expr *res, *new_expr;
432 gfc_actual_arglist *mask;
433
434 fn = *e;
435
436 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
437 || fn->value.function.isym == NULL)
438 return 0;
439
440 id = fn->value.function.isym->id;
441
442 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
443 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
444 return 0;
445
446 a = fn->value.function.actual;
447
448 /* Don't handle MASK or DIM. */
449
450 dim = a->next;
451
452 if (dim->expr != NULL)
453 return 0;
454
455 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
456 {
457 mask = dim->next;
458 if ( mask->expr != NULL)
459 return 0;
460 }
461
462 arg = a->expr;
463
464 if (arg->expr_type != EXPR_ARRAY)
465 return 0;
466
467 switch (id)
468 {
469 case GFC_ISYM_SUM:
470 op = INTRINSIC_PLUS;
471 break;
472
473 case GFC_ISYM_PRODUCT:
474 op = INTRINSIC_TIMES;
475 break;
476
477 case GFC_ISYM_ANY:
478 op = INTRINSIC_OR;
479 break;
480
481 case GFC_ISYM_ALL:
482 op = INTRINSIC_AND;
483 break;
484
485 default:
486 return 0;
487 }
488
489 c = gfc_constructor_first (arg->value.constructor);
490
491 /* Don't do any simplififcation if we have
492 - no element in the constructor or
493 - only have a single element in the array which contains an
494 iterator. */
495
496 if (c == NULL)
497 return 0;
498
499 res = copy_walk_reduction_arg (c, fn);
500
501 c = gfc_constructor_next (c);
502 while (c)
503 {
504 new_expr = gfc_get_expr ();
505 new_expr->ts = fn->ts;
506 new_expr->expr_type = EXPR_OP;
507 new_expr->rank = fn->rank;
508 new_expr->where = fn->where;
509 new_expr->value.op.op = op;
510 new_expr->value.op.op1 = res;
511 new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
512 res = new_expr;
513 c = gfc_constructor_next (c);
514 }
515
516 gfc_simplify_expr (res, 0);
517 *e = res;
518 gfc_free_expr (fn);
519
520 return 0;
521 }
522
523 /* Callback function for common function elimination, called from cfe_expr_0.
524 Put all eligible function expressions into expr_array. */
525
526 static int
527 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
528 void *data ATTRIBUTE_UNUSED)
529 {
530
531 if ((*e)->expr_type != EXPR_FUNCTION)
532 return 0;
533
534 /* We don't do character functions with unknown charlens. */
535 if ((*e)->ts.type == BT_CHARACTER
536 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
537 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
538 return 0;
539
540 /* We don't do function elimination within FORALL statements, it can
541 lead to wrong-code in certain circumstances. */
542
543 if (forall_level > 0)
544 return 0;
545
546 /* Function elimination inside an iterator could lead to functions which
547 depend on iterator variables being moved outside. FIXME: We should check
548 if the functions do indeed depend on the iterator variable. */
549
550 if (iterator_level > 0)
551 return 0;
552
553 /* If we don't know the shape at compile time, we create an allocatable
554 temporary variable to hold the intermediate result, but only if
555 allocation on assignment is active. */
556
557 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
558 return 0;
559
560 /* Skip the test for pure functions if -faggressive-function-elimination
561 is specified. */
562 if ((*e)->value.function.esym)
563 {
564 /* Don't create an array temporary for elemental functions. */
565 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
566 return 0;
567
568 /* Only eliminate potentially impure functions if the
569 user specifically requested it. */
570 if (!flag_aggressive_function_elimination
571 && !(*e)->value.function.esym->attr.pure
572 && !(*e)->value.function.esym->attr.implicit_pure)
573 return 0;
574 }
575
576 if ((*e)->value.function.isym)
577 {
578 /* Conversions are handled on the fly by the middle end,
579 transpose during trans-* stages and TRANSFER by the middle end. */
580 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
581 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
582 || gfc_inline_intrinsic_function_p (*e))
583 return 0;
584
585 /* Don't create an array temporary for elemental functions,
586 as this would be wasteful of memory.
587 FIXME: Create a scalar temporary during scalarization. */
588 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
589 return 0;
590
591 if (!(*e)->value.function.isym->pure)
592 return 0;
593 }
594
595 expr_array.safe_push (e);
596 return 0;
597 }
598
599 /* Auxiliary function to check if an expression is a temporary created by
600 create var. */
601
602 static bool
603 is_fe_temp (gfc_expr *e)
604 {
605 if (e->expr_type != EXPR_VARIABLE)
606 return false;
607
608 return e->symtree->n.sym->attr.fe_temp;
609 }
610
611 /* Determine the length of a string, if it can be evaluated as a constant
612 expression. Return a newly allocated gfc_expr or NULL on failure.
613 If the user specified a substring which is potentially longer than
614 the string itself, the string will be padded with spaces, which
615 is harmless. */
616
617 static gfc_expr *
618 constant_string_length (gfc_expr *e)
619 {
620
621 gfc_expr *length;
622 gfc_ref *ref;
623 gfc_expr *res;
624 mpz_t value;
625
626 if (e->ts.u.cl)
627 {
628 length = e->ts.u.cl->length;
629 if (length && length->expr_type == EXPR_CONSTANT)
630 return gfc_copy_expr(length);
631 }
632
633 /* Return length of substring, if constant. */
634 for (ref = e->ref; ref; ref = ref->next)
635 {
636 if (ref->type == REF_SUBSTRING
637 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
638 {
639 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
640 &e->where);
641
642 mpz_add_ui (res->value.integer, value, 1);
643 mpz_clear (value);
644 return res;
645 }
646 }
647
648 /* Return length of char symbol, if constant. */
649
650 if (e->symtree && e->symtree->n.sym->ts.u.cl
651 && e->symtree->n.sym->ts.u.cl->length
652 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
653 return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length);
654
655 return NULL;
656
657 }
658
659 /* Insert a block at the current position unless it has already
660 been inserted; in this case use the one already there. */
661
662 static gfc_namespace*
663 insert_block ()
664 {
665 gfc_namespace *ns;
666
667 /* If the block hasn't already been created, do so. */
668 if (inserted_block == NULL)
669 {
670 inserted_block = XCNEW (gfc_code);
671 inserted_block->op = EXEC_BLOCK;
672 inserted_block->loc = (*current_code)->loc;
673 ns = gfc_build_block_ns (current_ns);
674 inserted_block->ext.block.ns = ns;
675 inserted_block->ext.block.assoc = NULL;
676
677 ns->code = *current_code;
678
679 /* If the statement has a label, make sure it is transferred to
680 the newly created block. */
681
682 if ((*current_code)->here)
683 {
684 inserted_block->here = (*current_code)->here;
685 (*current_code)->here = NULL;
686 }
687
688 inserted_block->next = (*current_code)->next;
689 changed_statement = &(inserted_block->ext.block.ns->code);
690 (*current_code)->next = NULL;
691 /* Insert the BLOCK at the right position. */
692 *current_code = inserted_block;
693 ns->parent = current_ns;
694 }
695 else
696 ns = inserted_block->ext.block.ns;
697
698 return ns;
699 }
700
701 /* Returns a new expression (a variable) to be used in place of the old one,
702 with an optional assignment statement before the current statement to set
703 the value of the variable. Creates a new BLOCK for the statement if that
704 hasn't already been done and puts the statement, plus the newly created
705 variables, in that block. Special cases: If the expression is constant or
706 a temporary which has already been created, just copy it. */
707
708 static gfc_expr*
709 create_var (gfc_expr * e, const char *vname)
710 {
711 char name[GFC_MAX_SYMBOL_LEN +1];
712 gfc_symtree *symtree;
713 gfc_symbol *symbol;
714 gfc_expr *result;
715 gfc_code *n;
716 gfc_namespace *ns;
717 int i;
718 bool deferred;
719
720 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
721 return gfc_copy_expr (e);
722
723 /* Creation of an array of unknown size requires realloc on assignment.
724 If that is not possible, just return NULL. */
725 if (flag_realloc_lhs == 0 && e->rank > 0 && e->shape == NULL)
726 return NULL;
727
728 ns = insert_block ();
729
730 if (vname)
731 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d_%s", var_num++, vname);
732 else
733 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d", var_num++);
734
735 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
736 gcc_unreachable ();
737
738 symbol = symtree->n.sym;
739 symbol->ts = e->ts;
740
741 if (e->rank > 0)
742 {
743 symbol->as = gfc_get_array_spec ();
744 symbol->as->rank = e->rank;
745
746 if (e->shape == NULL)
747 {
748 /* We don't know the shape at compile time, so we use an
749 allocatable. */
750 symbol->as->type = AS_DEFERRED;
751 symbol->attr.allocatable = 1;
752 }
753 else
754 {
755 symbol->as->type = AS_EXPLICIT;
756 /* Copy the shape. */
757 for (i=0; i<e->rank; i++)
758 {
759 gfc_expr *p, *q;
760
761 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
762 &(e->where));
763 mpz_set_si (p->value.integer, 1);
764 symbol->as->lower[i] = p;
765
766 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
767 &(e->where));
768 mpz_set (q->value.integer, e->shape[i]);
769 symbol->as->upper[i] = q;
770 }
771 }
772 }
773
774 deferred = 0;
775 if (e->ts.type == BT_CHARACTER)
776 {
777 gfc_expr *length;
778
779 symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
780 length = constant_string_length (e);
781 if (length)
782 symbol->ts.u.cl->length = length;
783 else
784 {
785 symbol->attr.allocatable = 1;
786 symbol->ts.u.cl->length = NULL;
787 symbol->ts.deferred = 1;
788 deferred = 1;
789 }
790 }
791
792 symbol->attr.flavor = FL_VARIABLE;
793 symbol->attr.referenced = 1;
794 symbol->attr.dimension = e->rank > 0;
795 symbol->attr.fe_temp = 1;
796 gfc_commit_symbol (symbol);
797
798 result = gfc_get_expr ();
799 result->expr_type = EXPR_VARIABLE;
800 result->ts = symbol->ts;
801 result->ts.deferred = deferred;
802 result->rank = e->rank;
803 result->shape = gfc_copy_shape (e->shape, e->rank);
804 result->symtree = symtree;
805 result->where = e->where;
806 if (e->rank > 0)
807 {
808 result->ref = gfc_get_ref ();
809 result->ref->type = REF_ARRAY;
810 result->ref->u.ar.type = AR_FULL;
811 result->ref->u.ar.where = e->where;
812 result->ref->u.ar.dimen = e->rank;
813 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
814 ? CLASS_DATA (symbol)->as : symbol->as;
815 if (warn_array_temporaries)
816 gfc_warning (OPT_Warray_temporaries,
817 "Creating array temporary at %L", &(e->where));
818 }
819
820 /* Generate the new assignment. */
821 n = XCNEW (gfc_code);
822 n->op = EXEC_ASSIGN;
823 n->loc = (*current_code)->loc;
824 n->next = *changed_statement;
825 n->expr1 = gfc_copy_expr (result);
826 n->expr2 = e;
827 *changed_statement = n;
828 n_vars ++;
829
830 return result;
831 }
832
833 /* Warn about function elimination. */
834
835 static void
836 do_warn_function_elimination (gfc_expr *e)
837 {
838 if (e->expr_type != EXPR_FUNCTION)
839 return;
840 if (e->value.function.esym)
841 gfc_warning (OPT_Wfunction_elimination,
842 "Removing call to function %qs at %L",
843 e->value.function.esym->name, &(e->where));
844 else if (e->value.function.isym)
845 gfc_warning (OPT_Wfunction_elimination,
846 "Removing call to function %qs at %L",
847 e->value.function.isym->name, &(e->where));
848 }
849 /* Callback function for the code walker for doing common function
850 elimination. This builds up the list of functions in the expression
851 and goes through them to detect duplicates, which it then replaces
852 by variables. */
853
854 static int
855 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
856 void *data ATTRIBUTE_UNUSED)
857 {
858 int i,j;
859 gfc_expr *newvar;
860 gfc_expr **ei, **ej;
861
862 /* Don't do this optimization within OMP workshare or ASSOC lists. */
863
864 if (in_omp_workshare || in_assoc_list)
865 {
866 *walk_subtrees = 0;
867 return 0;
868 }
869
870 expr_array.release ();
871
872 gfc_expr_walker (e, cfe_register_funcs, NULL);
873
874 /* Walk through all the functions. */
875
876 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
877 {
878 /* Skip if the function has been replaced by a variable already. */
879 if ((*ei)->expr_type == EXPR_VARIABLE)
880 continue;
881
882 newvar = NULL;
883 for (j=0; j<i; j++)
884 {
885 ej = expr_array[j];
886 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
887 {
888 if (newvar == NULL)
889 newvar = create_var (*ei, "fcn");
890
891 if (warn_function_elimination)
892 do_warn_function_elimination (*ej);
893
894 free (*ej);
895 *ej = gfc_copy_expr (newvar);
896 }
897 }
898 if (newvar)
899 *ei = newvar;
900 }
901
902 /* We did all the necessary walking in this function. */
903 *walk_subtrees = 0;
904 return 0;
905 }
906
907 /* Callback function for common function elimination, called from
908 gfc_code_walker. This keeps track of the current code, in order
909 to insert statements as needed. */
910
911 static int
912 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
913 {
914 current_code = c;
915 inserted_block = NULL;
916 changed_statement = NULL;
917
918 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
919 and allocation on assigment are prohibited inside WHERE, and finally
920 masking an expression would lead to wrong-code when replacing
921
922 WHERE (a>0)
923 b = sum(foo(a) + foo(a))
924 END WHERE
925
926 with
927
928 WHERE (a > 0)
929 tmp = foo(a)
930 b = sum(tmp + tmp)
931 END WHERE
932 */
933
934 if ((*c)->op == EXEC_WHERE)
935 {
936 *walk_subtrees = 0;
937 return 0;
938 }
939
940
941 return 0;
942 }
943
944 /* Dummy function for expression call back, for use when we
945 really don't want to do any walking. */
946
947 static int
948 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
949 void *data ATTRIBUTE_UNUSED)
950 {
951 *walk_subtrees = 0;
952 return 0;
953 }
954
955 /* Dummy function for code callback, for use when we really
956 don't want to do anything. */
957 int
958 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
959 int *walk_subtrees ATTRIBUTE_UNUSED,
960 void *data ATTRIBUTE_UNUSED)
961 {
962 return 0;
963 }
964
965 /* Code callback function for converting
966 do while(a)
967 end do
968 into the equivalent
969 do
970 if (.not. a) exit
971 end do
972 This is because common function elimination would otherwise place the
973 temporary variables outside the loop. */
974
975 static int
976 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
977 void *data ATTRIBUTE_UNUSED)
978 {
979 gfc_code *co = *c;
980 gfc_code *c_if1, *c_if2, *c_exit;
981 gfc_code *loopblock;
982 gfc_expr *e_not, *e_cond;
983
984 if (co->op != EXEC_DO_WHILE)
985 return 0;
986
987 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
988 return 0;
989
990 e_cond = co->expr1;
991
992 /* Generate the condition of the if statement, which is .not. the original
993 statement. */
994 e_not = gfc_get_expr ();
995 e_not->ts = e_cond->ts;
996 e_not->where = e_cond->where;
997 e_not->expr_type = EXPR_OP;
998 e_not->value.op.op = INTRINSIC_NOT;
999 e_not->value.op.op1 = e_cond;
1000
1001 /* Generate the EXIT statement. */
1002 c_exit = XCNEW (gfc_code);
1003 c_exit->op = EXEC_EXIT;
1004 c_exit->ext.which_construct = co;
1005 c_exit->loc = co->loc;
1006
1007 /* Generate the IF statement. */
1008 c_if2 = XCNEW (gfc_code);
1009 c_if2->op = EXEC_IF;
1010 c_if2->expr1 = e_not;
1011 c_if2->next = c_exit;
1012 c_if2->loc = co->loc;
1013
1014 /* ... plus the one to chain it to. */
1015 c_if1 = XCNEW (gfc_code);
1016 c_if1->op = EXEC_IF;
1017 c_if1->block = c_if2;
1018 c_if1->loc = co->loc;
1019
1020 /* Make the DO WHILE loop into a DO block by replacing the condition
1021 with a true constant. */
1022 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
1023
1024 /* Hang the generated if statement into the loop body. */
1025
1026 loopblock = co->block->next;
1027 co->block->next = c_if1;
1028 c_if1->next = loopblock;
1029
1030 return 0;
1031 }
1032
1033 /* Code callback function for converting
1034 if (a) then
1035 ...
1036 else if (b) then
1037 end if
1038
1039 into
1040 if (a) then
1041 else
1042 if (b) then
1043 end if
1044 end if
1045
1046 because otherwise common function elimination would place the BLOCKs
1047 into the wrong place. */
1048
1049 static int
1050 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1051 void *data ATTRIBUTE_UNUSED)
1052 {
1053 gfc_code *co = *c;
1054 gfc_code *c_if1, *c_if2, *else_stmt;
1055
1056 if (co->op != EXEC_IF)
1057 return 0;
1058
1059 /* This loop starts out with the first ELSE statement. */
1060 else_stmt = co->block->block;
1061
1062 while (else_stmt != NULL)
1063 {
1064 gfc_code *next_else;
1065
1066 /* If there is no condition, we're done. */
1067 if (else_stmt->expr1 == NULL)
1068 break;
1069
1070 next_else = else_stmt->block;
1071
1072 /* Generate the new IF statement. */
1073 c_if2 = XCNEW (gfc_code);
1074 c_if2->op = EXEC_IF;
1075 c_if2->expr1 = else_stmt->expr1;
1076 c_if2->next = else_stmt->next;
1077 c_if2->loc = else_stmt->loc;
1078 c_if2->block = next_else;
1079
1080 /* ... plus the one to chain it to. */
1081 c_if1 = XCNEW (gfc_code);
1082 c_if1->op = EXEC_IF;
1083 c_if1->block = c_if2;
1084 c_if1->loc = else_stmt->loc;
1085
1086 /* Insert the new IF after the ELSE. */
1087 else_stmt->expr1 = NULL;
1088 else_stmt->next = c_if1;
1089 else_stmt->block = NULL;
1090
1091 else_stmt = next_else;
1092 }
1093 /* Don't walk subtrees. */
1094 return 0;
1095 }
1096
1097 struct do_stack
1098 {
1099 struct do_stack *prev;
1100 gfc_iterator *iter;
1101 gfc_code *code;
1102 } *stack_top;
1103
1104 /* Recursively traverse the block of a WRITE or READ statement, and maybe
1105 optimize by replacing do loops with their analog array slices. For
1106 example:
1107
1108 write (*,*) (a(i), i=1,4)
1109
1110 is replaced with
1111
1112 write (*,*) a(1:4:1) . */
1113
1114 static bool
1115 traverse_io_block (gfc_code *code, bool *has_reached, gfc_code *prev)
1116 {
1117 gfc_code *curr;
1118 gfc_expr *new_e, *expr, *start;
1119 gfc_ref *ref;
1120 struct do_stack ds_push;
1121 int i, future_rank = 0;
1122 gfc_iterator *iters[GFC_MAX_DIMENSIONS];
1123 gfc_expr *e;
1124
1125 /* Find the first transfer/do statement. */
1126 for (curr = code; curr; curr = curr->next)
1127 {
1128 if (curr->op == EXEC_DO || curr->op == EXEC_TRANSFER)
1129 break;
1130 }
1131
1132 /* Ensure it is the only transfer/do statement because cases like
1133
1134 write (*,*) (a(i), b(i), i=1,4)
1135
1136 cannot be optimized. */
1137
1138 if (!curr || curr->next)
1139 return false;
1140
1141 if (curr->op == EXEC_DO)
1142 {
1143 if (curr->ext.iterator->var->ref)
1144 return false;
1145 ds_push.prev = stack_top;
1146 ds_push.iter = curr->ext.iterator;
1147 ds_push.code = curr;
1148 stack_top = &ds_push;
1149 if (traverse_io_block (curr->block->next, has_reached, prev))
1150 {
1151 if (curr != stack_top->code && !*has_reached)
1152 {
1153 curr->block->next = NULL;
1154 gfc_free_statements (curr);
1155 }
1156 else
1157 *has_reached = true;
1158 return true;
1159 }
1160 return false;
1161 }
1162
1163 gcc_assert (curr->op == EXEC_TRANSFER);
1164
1165 e = curr->expr1;
1166 ref = e->ref;
1167 if (!ref || ref->type != REF_ARRAY || ref->u.ar.codimen != 0 || ref->next)
1168 return false;
1169
1170 /* Find the iterators belonging to each variable and check conditions. */
1171 for (i = 0; i < ref->u.ar.dimen; i++)
1172 {
1173 if (!ref->u.ar.start[i] || ref->u.ar.start[i]->ref
1174 || ref->u.ar.dimen_type[i] != DIMEN_ELEMENT)
1175 return false;
1176
1177 start = ref->u.ar.start[i];
1178 gfc_simplify_expr (start, 0);
1179 switch (start->expr_type)
1180 {
1181 case EXPR_VARIABLE:
1182
1183 /* write (*,*) (a(i), i=a%b,1) not handled yet. */
1184 if (start->ref)
1185 return false;
1186
1187 /* Check for (a(k), i=1,4) or ((a(j, i), i=1,4), j=1,4). */
1188 if (!stack_top || !stack_top->iter
1189 || stack_top->iter->var->symtree != start->symtree)
1190 {
1191 /* Check for (a(i,i), i=1,3). */
1192 int j;
1193
1194 for (j=0; j<i; j++)
1195 if (iters[j] && iters[j]->var->symtree == start->symtree)
1196 return false;
1197
1198 iters[i] = NULL;
1199 }
1200 else
1201 {
1202 iters[i] = stack_top->iter;
1203 stack_top = stack_top->prev;
1204 future_rank++;
1205 }
1206 break;
1207 case EXPR_CONSTANT:
1208 iters[i] = NULL;
1209 break;
1210 case EXPR_OP:
1211 switch (start->value.op.op)
1212 {
1213 case INTRINSIC_PLUS:
1214 case INTRINSIC_TIMES:
1215 if (start->value.op.op1->expr_type != EXPR_VARIABLE)
1216 std::swap (start->value.op.op1, start->value.op.op2);
1217 gcc_fallthrough ();
1218 case INTRINSIC_MINUS:
1219 if ((start->value.op.op1->expr_type!= EXPR_VARIABLE
1220 && start->value.op.op2->expr_type != EXPR_CONSTANT)
1221 || start->value.op.op1->ref)
1222 return false;
1223 if (!stack_top || !stack_top->iter
1224 || stack_top->iter->var->symtree
1225 != start->value.op.op1->symtree)
1226 return false;
1227 iters[i] = stack_top->iter;
1228 stack_top = stack_top->prev;
1229 break;
1230 default:
1231 return false;
1232 }
1233 future_rank++;
1234 break;
1235 default:
1236 return false;
1237 }
1238 }
1239
1240 /* Check for cases like ((a(i, j), i=1, j), j=1, 2). */
1241 for (int i = 1; i < ref->u.ar.dimen; i++)
1242 {
1243 if (iters[i])
1244 {
1245 gfc_expr *var = iters[i]->var;
1246 for (int j = i - 1; j < i; j++)
1247 {
1248 if (iters[j]
1249 && (gfc_check_dependency (var, iters[j]->start, true)
1250 || gfc_check_dependency (var, iters[j]->end, true)
1251 || gfc_check_dependency (var, iters[j]->step, true)))
1252 return false;
1253 }
1254 }
1255 }
1256
1257 /* Create new expr. */
1258 new_e = gfc_copy_expr (curr->expr1);
1259 new_e->expr_type = EXPR_VARIABLE;
1260 new_e->rank = future_rank;
1261 if (curr->expr1->shape)
1262 new_e->shape = gfc_get_shape (new_e->rank);
1263
1264 /* Assign new starts, ends and strides if necessary. */
1265 for (i = 0; i < ref->u.ar.dimen; i++)
1266 {
1267 if (!iters[i])
1268 continue;
1269 start = ref->u.ar.start[i];
1270 switch (start->expr_type)
1271 {
1272 case EXPR_CONSTANT:
1273 gfc_internal_error ("bad expression");
1274 break;
1275 case EXPR_VARIABLE:
1276 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1277 new_e->ref->u.ar.type = AR_SECTION;
1278 gfc_free_expr (new_e->ref->u.ar.start[i]);
1279 new_e->ref->u.ar.start[i] = gfc_copy_expr (iters[i]->start);
1280 new_e->ref->u.ar.end[i] = gfc_copy_expr (iters[i]->end);
1281 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1282 break;
1283 case EXPR_OP:
1284 new_e->ref->u.ar.dimen_type[i] = DIMEN_RANGE;
1285 new_e->ref->u.ar.type = AR_SECTION;
1286 gfc_free_expr (new_e->ref->u.ar.start[i]);
1287 expr = gfc_copy_expr (start);
1288 expr->value.op.op1 = gfc_copy_expr (iters[i]->start);
1289 new_e->ref->u.ar.start[i] = expr;
1290 gfc_simplify_expr (new_e->ref->u.ar.start[i], 0);
1291 expr = gfc_copy_expr (start);
1292 expr->value.op.op1 = gfc_copy_expr (iters[i]->end);
1293 new_e->ref->u.ar.end[i] = expr;
1294 gfc_simplify_expr (new_e->ref->u.ar.end[i], 0);
1295 switch (start->value.op.op)
1296 {
1297 case INTRINSIC_MINUS:
1298 case INTRINSIC_PLUS:
1299 new_e->ref->u.ar.stride[i] = gfc_copy_expr (iters[i]->step);
1300 break;
1301 case INTRINSIC_TIMES:
1302 expr = gfc_copy_expr (start);
1303 expr->value.op.op1 = gfc_copy_expr (iters[i]->step);
1304 new_e->ref->u.ar.stride[i] = expr;
1305 gfc_simplify_expr (new_e->ref->u.ar.stride[i], 0);
1306 break;
1307 default:
1308 gfc_internal_error ("bad op");
1309 }
1310 break;
1311 default:
1312 gfc_internal_error ("bad expression");
1313 }
1314 }
1315 curr->expr1 = new_e;
1316
1317 /* Insert modified statement. Check whether the statement needs to be
1318 inserted at the lowest level. */
1319 if (!stack_top->iter)
1320 {
1321 if (prev)
1322 {
1323 curr->next = prev->next->next;
1324 prev->next = curr;
1325 }
1326 else
1327 {
1328 curr->next = stack_top->code->block->next->next->next;
1329 stack_top->code->block->next = curr;
1330 }
1331 }
1332 else
1333 stack_top->code->block->next = curr;
1334 return true;
1335 }
1336
1337 /* Function for the gfc_code_walker. If code is a READ or WRITE statement, it
1338 tries to optimize its block. */
1339
1340 static int
1341 simplify_io_impl_do (gfc_code **code, int *walk_subtrees,
1342 void *data ATTRIBUTE_UNUSED)
1343 {
1344 gfc_code **curr, *prev = NULL;
1345 struct do_stack write, first;
1346 bool b = false;
1347 *walk_subtrees = 1;
1348 if (!(*code)->block
1349 || ((*code)->block->op != EXEC_WRITE
1350 && (*code)->block->op != EXEC_READ))
1351 return 0;
1352
1353 *walk_subtrees = 0;
1354 write.prev = NULL;
1355 write.iter = NULL;
1356 write.code = *code;
1357
1358 for (curr = &(*code)->block; *curr; curr = &(*curr)->next)
1359 {
1360 if ((*curr)->op == EXEC_DO)
1361 {
1362 first.prev = &write;
1363 first.iter = (*curr)->ext.iterator;
1364 first.code = *curr;
1365 stack_top = &first;
1366 traverse_io_block ((*curr)->block->next, &b, prev);
1367 stack_top = NULL;
1368 }
1369 prev = *curr;
1370 }
1371 return 0;
1372 }
1373
1374 /* Optimize a namespace, including all contained namespaces.
1375 flag_frontend_optimize and flag_fronend_loop_interchange are
1376 handled separately. */
1377
1378 static void
1379 optimize_namespace (gfc_namespace *ns)
1380 {
1381 gfc_namespace *saved_ns = gfc_current_ns;
1382 current_ns = ns;
1383 gfc_current_ns = ns;
1384 forall_level = 0;
1385 iterator_level = 0;
1386 in_assoc_list = false;
1387 in_omp_workshare = false;
1388
1389 if (flag_frontend_optimize)
1390 {
1391 gfc_code_walker (&ns->code, simplify_io_impl_do, dummy_expr_callback, NULL);
1392 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
1393 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
1394 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
1395 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
1396 if (flag_inline_matmul_limit != 0)
1397 {
1398 bool found;
1399 do
1400 {
1401 found = false;
1402 gfc_code_walker (&ns->code, matmul_to_var_code, matmul_to_var_expr,
1403 (void *) &found);
1404 }
1405 while (found);
1406
1407 gfc_code_walker (&ns->code, matmul_temp_args, dummy_expr_callback,
1408 NULL);
1409 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
1410 NULL);
1411 }
1412 }
1413
1414 if (flag_frontend_loop_interchange)
1415 gfc_code_walker (&ns->code, index_interchange, dummy_expr_callback,
1416 NULL);
1417
1418 /* BLOCKs are handled in the expression walker below. */
1419 for (ns = ns->contained; ns; ns = ns->sibling)
1420 {
1421 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1422 optimize_namespace (ns);
1423 }
1424 gfc_current_ns = saved_ns;
1425 }
1426
1427 /* Handle dependencies for allocatable strings which potentially redefine
1428 themselves in an assignment. */
1429
1430 static void
1431 realloc_strings (gfc_namespace *ns)
1432 {
1433 current_ns = ns;
1434 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1435
1436 for (ns = ns->contained; ns; ns = ns->sibling)
1437 {
1438 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1439 realloc_strings (ns);
1440 }
1441
1442 }
1443
1444 static void
1445 optimize_reduction (gfc_namespace *ns)
1446 {
1447 current_ns = ns;
1448 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1449 callback_reduction, NULL);
1450
1451 /* BLOCKs are handled in the expression walker below. */
1452 for (ns = ns->contained; ns; ns = ns->sibling)
1453 {
1454 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1455 optimize_reduction (ns);
1456 }
1457 }
1458
1459 /* Replace code like
1460 a = matmul(b,c) + d
1461 with
1462 a = matmul(b,c) ; a = a + d
1463 where the array function is not elemental and not allocatable
1464 and does not depend on the left-hand side.
1465 */
1466
1467 static bool
1468 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1469 {
1470 gfc_expr *e;
1471
1472 if (!*rhs)
1473 return false;
1474
1475 e = *rhs;
1476 if (e->expr_type == EXPR_OP)
1477 {
1478 switch (e->value.op.op)
1479 {
1480 /* Unary operators and exponentiation: Only look at a single
1481 operand. */
1482 case INTRINSIC_NOT:
1483 case INTRINSIC_UPLUS:
1484 case INTRINSIC_UMINUS:
1485 case INTRINSIC_PARENTHESES:
1486 case INTRINSIC_POWER:
1487 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
1488 return true;
1489 break;
1490
1491 case INTRINSIC_CONCAT:
1492 /* Do not do string concatenations. */
1493 break;
1494
1495 default:
1496 /* Binary operators. */
1497 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1498 return true;
1499
1500 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1501 return true;
1502
1503 break;
1504 }
1505 }
1506 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
1507 && ! (e->value.function.esym
1508 && (e->value.function.esym->attr.elemental
1509 || e->value.function.esym->attr.allocatable
1510 || e->value.function.esym->ts.type != c->expr1->ts.type
1511 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
1512 && ! (e->value.function.isym
1513 && (e->value.function.isym->elemental
1514 || e->ts.type != c->expr1->ts.type
1515 || e->ts.kind != c->expr1->ts.kind))
1516 && ! gfc_inline_intrinsic_function_p (e))
1517 {
1518
1519 gfc_code *n;
1520 gfc_expr *new_expr;
1521
1522 /* Insert a new assignment statement after the current one. */
1523 n = XCNEW (gfc_code);
1524 n->op = EXEC_ASSIGN;
1525 n->loc = c->loc;
1526 n->next = c->next;
1527 c->next = n;
1528
1529 n->expr1 = gfc_copy_expr (c->expr1);
1530 n->expr2 = c->expr2;
1531 new_expr = gfc_copy_expr (c->expr1);
1532 c->expr2 = e;
1533 *rhs = new_expr;
1534
1535 return true;
1536
1537 }
1538
1539 /* Nothing to optimize. */
1540 return false;
1541 }
1542
1543 /* Remove unneeded TRIMs at the end of expressions. */
1544
1545 static bool
1546 remove_trim (gfc_expr *rhs)
1547 {
1548 bool ret;
1549
1550 ret = false;
1551 if (!rhs)
1552 return ret;
1553
1554 /* Check for a // b // trim(c). Looping is probably not
1555 necessary because the parser usually generates
1556 (// (// a b ) trim(c) ) , but better safe than sorry. */
1557
1558 while (rhs->expr_type == EXPR_OP
1559 && rhs->value.op.op == INTRINSIC_CONCAT)
1560 rhs = rhs->value.op.op2;
1561
1562 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1563 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1564 {
1565 strip_function_call (rhs);
1566 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1567 remove_trim (rhs);
1568 ret = true;
1569 }
1570
1571 return ret;
1572 }
1573
1574 /* Optimizations for an assignment. */
1575
1576 static void
1577 optimize_assignment (gfc_code * c)
1578 {
1579 gfc_expr *lhs, *rhs;
1580
1581 lhs = c->expr1;
1582 rhs = c->expr2;
1583
1584 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1585 {
1586 /* Optimize a = trim(b) to a = b. */
1587 remove_trim (rhs);
1588
1589 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1590 if (is_empty_string (rhs))
1591 rhs->value.character.length = 0;
1592 }
1593
1594 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1595 optimize_binop_array_assignment (c, &rhs, false);
1596 }
1597
1598
1599 /* Remove an unneeded function call, modifying the expression.
1600 This replaces the function call with the value of its
1601 first argument. The rest of the argument list is freed. */
1602
1603 static void
1604 strip_function_call (gfc_expr *e)
1605 {
1606 gfc_expr *e1;
1607 gfc_actual_arglist *a;
1608
1609 a = e->value.function.actual;
1610
1611 /* We should have at least one argument. */
1612 gcc_assert (a->expr != NULL);
1613
1614 e1 = a->expr;
1615
1616 /* Free the remaining arglist, if any. */
1617 if (a->next)
1618 gfc_free_actual_arglist (a->next);
1619
1620 /* Graft the argument expression onto the original function. */
1621 *e = *e1;
1622 free (e1);
1623
1624 }
1625
1626 /* Optimization of lexical comparison functions. */
1627
1628 static bool
1629 optimize_lexical_comparison (gfc_expr *e)
1630 {
1631 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1632 return false;
1633
1634 switch (e->value.function.isym->id)
1635 {
1636 case GFC_ISYM_LLE:
1637 return optimize_comparison (e, INTRINSIC_LE);
1638
1639 case GFC_ISYM_LGE:
1640 return optimize_comparison (e, INTRINSIC_GE);
1641
1642 case GFC_ISYM_LGT:
1643 return optimize_comparison (e, INTRINSIC_GT);
1644
1645 case GFC_ISYM_LLT:
1646 return optimize_comparison (e, INTRINSIC_LT);
1647
1648 default:
1649 break;
1650 }
1651 return false;
1652 }
1653
1654 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1655 do CHARACTER because of possible pessimization involving character
1656 lengths. */
1657
1658 static bool
1659 combine_array_constructor (gfc_expr *e)
1660 {
1661
1662 gfc_expr *op1, *op2;
1663 gfc_expr *scalar;
1664 gfc_expr *new_expr;
1665 gfc_constructor *c, *new_c;
1666 gfc_constructor_base oldbase, newbase;
1667 bool scalar_first;
1668 int n_elem;
1669 bool all_const;
1670
1671 /* Array constructors have rank one. */
1672 if (e->rank != 1)
1673 return false;
1674
1675 /* Don't try to combine association lists, this makes no sense
1676 and leads to an ICE. */
1677 if (in_assoc_list)
1678 return false;
1679
1680 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1681 if (forall_level > 0)
1682 return false;
1683
1684 /* Inside an iterator, things can get hairy; we are likely to create
1685 an invalid temporary variable. */
1686 if (iterator_level > 0)
1687 return false;
1688
1689 op1 = e->value.op.op1;
1690 op2 = e->value.op.op2;
1691
1692 if (!op1 || !op2)
1693 return false;
1694
1695 if (op1->expr_type == EXPR_ARRAY && op2->rank == 0)
1696 scalar_first = false;
1697 else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0)
1698 {
1699 scalar_first = true;
1700 op1 = e->value.op.op2;
1701 op2 = e->value.op.op1;
1702 }
1703 else
1704 return false;
1705
1706 if (op2->ts.type == BT_CHARACTER)
1707 return false;
1708
1709 /* This might be an expanded constructor with very many constant values. If
1710 we perform the operation here, we might end up with a long compile time
1711 and actually longer execution time, so a length bound is in order here.
1712 If the constructor constains something which is not a constant, it did
1713 not come from an expansion, so leave it alone. */
1714
1715 #define CONSTR_LEN_MAX 4
1716
1717 oldbase = op1->value.constructor;
1718
1719 n_elem = 0;
1720 all_const = true;
1721 for (c = gfc_constructor_first (oldbase); c; c = gfc_constructor_next(c))
1722 {
1723 if (c->expr->expr_type != EXPR_CONSTANT)
1724 {
1725 all_const = false;
1726 break;
1727 }
1728 n_elem += 1;
1729 }
1730
1731 if (all_const && n_elem > CONSTR_LEN_MAX)
1732 return false;
1733
1734 #undef CONSTR_LEN_MAX
1735
1736 newbase = NULL;
1737 e->expr_type = EXPR_ARRAY;
1738
1739 scalar = create_var (gfc_copy_expr (op2), "constr");
1740
1741 for (c = gfc_constructor_first (oldbase); c;
1742 c = gfc_constructor_next (c))
1743 {
1744 new_expr = gfc_get_expr ();
1745 new_expr->ts = e->ts;
1746 new_expr->expr_type = EXPR_OP;
1747 new_expr->rank = c->expr->rank;
1748 new_expr->where = c->expr->where;
1749 new_expr->value.op.op = e->value.op.op;
1750
1751 if (scalar_first)
1752 {
1753 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1754 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1755 }
1756 else
1757 {
1758 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1759 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1760 }
1761
1762 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1763 new_c->iterator = c->iterator;
1764 c->iterator = NULL;
1765 }
1766
1767 gfc_free_expr (op1);
1768 gfc_free_expr (op2);
1769 gfc_free_expr (scalar);
1770
1771 e->value.constructor = newbase;
1772 return true;
1773 }
1774
1775 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1776 2**k into ishift(1,k) */
1777
1778 static bool
1779 optimize_power (gfc_expr *e)
1780 {
1781 gfc_expr *op1, *op2;
1782 gfc_expr *iand, *ishft;
1783
1784 if (e->ts.type != BT_INTEGER)
1785 return false;
1786
1787 op1 = e->value.op.op1;
1788
1789 if (op1 == NULL || op1->expr_type != EXPR_CONSTANT)
1790 return false;
1791
1792 if (mpz_cmp_si (op1->value.integer, -1L) == 0)
1793 {
1794 gfc_free_expr (op1);
1795
1796 op2 = e->value.op.op2;
1797
1798 if (op2 == NULL)
1799 return false;
1800
1801 iand = gfc_build_intrinsic_call (current_ns, GFC_ISYM_IAND,
1802 "_internal_iand", e->where, 2, op2,
1803 gfc_get_int_expr (e->ts.kind,
1804 &e->where, 1));
1805
1806 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1807 "_internal_ishft", e->where, 2, iand,
1808 gfc_get_int_expr (e->ts.kind,
1809 &e->where, 1));
1810
1811 e->value.op.op = INTRINSIC_MINUS;
1812 e->value.op.op1 = gfc_get_int_expr (e->ts.kind, &e->where, 1);
1813 e->value.op.op2 = ishft;
1814 return true;
1815 }
1816 else if (mpz_cmp_si (op1->value.integer, 2L) == 0)
1817 {
1818 gfc_free_expr (op1);
1819
1820 op2 = e->value.op.op2;
1821 if (op2 == NULL)
1822 return false;
1823
1824 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1825 "_internal_ishft", e->where, 2,
1826 gfc_get_int_expr (e->ts.kind,
1827 &e->where, 1),
1828 op2);
1829 *e = *ishft;
1830 return true;
1831 }
1832
1833 else if (mpz_cmp_si (op1->value.integer, 1L) == 0)
1834 {
1835 op2 = e->value.op.op2;
1836 if (op2 == NULL)
1837 return false;
1838
1839 gfc_free_expr (op1);
1840 gfc_free_expr (op2);
1841
1842 e->expr_type = EXPR_CONSTANT;
1843 e->value.op.op1 = NULL;
1844 e->value.op.op2 = NULL;
1845 mpz_init_set_si (e->value.integer, 1);
1846 /* Typespec and location are still OK. */
1847 return true;
1848 }
1849
1850 return false;
1851 }
1852
1853 /* Recursive optimization of operators. */
1854
1855 static bool
1856 optimize_op (gfc_expr *e)
1857 {
1858 bool changed;
1859
1860 gfc_intrinsic_op op = e->value.op.op;
1861
1862 changed = false;
1863
1864 /* Only use new-style comparisons. */
1865 switch(op)
1866 {
1867 case INTRINSIC_EQ_OS:
1868 op = INTRINSIC_EQ;
1869 break;
1870
1871 case INTRINSIC_GE_OS:
1872 op = INTRINSIC_GE;
1873 break;
1874
1875 case INTRINSIC_LE_OS:
1876 op = INTRINSIC_LE;
1877 break;
1878
1879 case INTRINSIC_NE_OS:
1880 op = INTRINSIC_NE;
1881 break;
1882
1883 case INTRINSIC_GT_OS:
1884 op = INTRINSIC_GT;
1885 break;
1886
1887 case INTRINSIC_LT_OS:
1888 op = INTRINSIC_LT;
1889 break;
1890
1891 default:
1892 break;
1893 }
1894
1895 switch (op)
1896 {
1897 case INTRINSIC_EQ:
1898 case INTRINSIC_GE:
1899 case INTRINSIC_LE:
1900 case INTRINSIC_NE:
1901 case INTRINSIC_GT:
1902 case INTRINSIC_LT:
1903 changed = optimize_comparison (e, op);
1904
1905 gcc_fallthrough ();
1906 /* Look at array constructors. */
1907 case INTRINSIC_PLUS:
1908 case INTRINSIC_MINUS:
1909 case INTRINSIC_TIMES:
1910 case INTRINSIC_DIVIDE:
1911 return combine_array_constructor (e) || changed;
1912
1913 case INTRINSIC_POWER:
1914 return optimize_power (e);
1915
1916 default:
1917 break;
1918 }
1919
1920 return false;
1921 }
1922
1923
1924 /* Return true if a constant string contains only blanks. */
1925
1926 static bool
1927 is_empty_string (gfc_expr *e)
1928 {
1929 int i;
1930
1931 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1932 return false;
1933
1934 for (i=0; i < e->value.character.length; i++)
1935 {
1936 if (e->value.character.string[i] != ' ')
1937 return false;
1938 }
1939
1940 return true;
1941 }
1942
1943
1944 /* Insert a call to the intrinsic len_trim. Use a different name for
1945 the symbol tree so we don't run into trouble when the user has
1946 renamed len_trim for some reason. */
1947
1948 static gfc_expr*
1949 get_len_trim_call (gfc_expr *str, int kind)
1950 {
1951 gfc_expr *fcn;
1952 gfc_actual_arglist *actual_arglist, *next;
1953
1954 fcn = gfc_get_expr ();
1955 fcn->expr_type = EXPR_FUNCTION;
1956 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1957 actual_arglist = gfc_get_actual_arglist ();
1958 actual_arglist->expr = str;
1959 next = gfc_get_actual_arglist ();
1960 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, kind);
1961 actual_arglist->next = next;
1962
1963 fcn->value.function.actual = actual_arglist;
1964 fcn->where = str->where;
1965 fcn->ts.type = BT_INTEGER;
1966 fcn->ts.kind = gfc_charlen_int_kind;
1967
1968 gfc_get_sym_tree ("__internal_len_trim", current_ns, &fcn->symtree, false);
1969 fcn->symtree->n.sym->ts = fcn->ts;
1970 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1971 fcn->symtree->n.sym->attr.function = 1;
1972 fcn->symtree->n.sym->attr.elemental = 1;
1973 fcn->symtree->n.sym->attr.referenced = 1;
1974 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
1975 gfc_commit_symbol (fcn->symtree->n.sym);
1976
1977 return fcn;
1978 }
1979
1980 /* Optimize expressions for equality. */
1981
1982 static bool
1983 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1984 {
1985 gfc_expr *op1, *op2;
1986 bool change;
1987 int eq;
1988 bool result;
1989 gfc_actual_arglist *firstarg, *secondarg;
1990
1991 if (e->expr_type == EXPR_OP)
1992 {
1993 firstarg = NULL;
1994 secondarg = NULL;
1995 op1 = e->value.op.op1;
1996 op2 = e->value.op.op2;
1997 }
1998 else if (e->expr_type == EXPR_FUNCTION)
1999 {
2000 /* One of the lexical comparison functions. */
2001 firstarg = e->value.function.actual;
2002 secondarg = firstarg->next;
2003 op1 = firstarg->expr;
2004 op2 = secondarg->expr;
2005 }
2006 else
2007 gcc_unreachable ();
2008
2009 /* Strip off unneeded TRIM calls from string comparisons. */
2010
2011 change = remove_trim (op1);
2012
2013 if (remove_trim (op2))
2014 change = true;
2015
2016 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
2017 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
2018 handles them well). However, there are also cases that need a non-scalar
2019 argument. For example the any intrinsic. See PR 45380. */
2020 if (e->rank > 0)
2021 return change;
2022
2023 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
2024 len_trim(a) != 0 */
2025 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
2026 && (op == INTRINSIC_EQ || op == INTRINSIC_NE))
2027 {
2028 bool empty_op1, empty_op2;
2029 empty_op1 = is_empty_string (op1);
2030 empty_op2 = is_empty_string (op2);
2031
2032 if (empty_op1 || empty_op2)
2033 {
2034 gfc_expr *fcn;
2035 gfc_expr *zero;
2036 gfc_expr *str;
2037
2038 /* This can only happen when an error for comparing
2039 characters of different kinds has already been issued. */
2040 if (empty_op1 && empty_op2)
2041 return false;
2042
2043 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
2044 str = empty_op1 ? op2 : op1;
2045
2046 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
2047
2048
2049 if (empty_op1)
2050 gfc_free_expr (op1);
2051 else
2052 gfc_free_expr (op2);
2053
2054 op1 = fcn;
2055 op2 = zero;
2056 e->value.op.op1 = fcn;
2057 e->value.op.op2 = zero;
2058 }
2059 }
2060
2061
2062 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
2063
2064 if (flag_finite_math_only
2065 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
2066 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
2067 {
2068 eq = gfc_dep_compare_expr (op1, op2);
2069 if (eq <= -2)
2070 {
2071 /* Replace A // B < A // C with B < C, and A // B < C // B
2072 with A < C. */
2073 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
2074 && op1->expr_type == EXPR_OP
2075 && op1->value.op.op == INTRINSIC_CONCAT
2076 && op2->expr_type == EXPR_OP
2077 && op2->value.op.op == INTRINSIC_CONCAT)
2078 {
2079 gfc_expr *op1_left = op1->value.op.op1;
2080 gfc_expr *op2_left = op2->value.op.op1;
2081 gfc_expr *op1_right = op1->value.op.op2;
2082 gfc_expr *op2_right = op2->value.op.op2;
2083
2084 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
2085 {
2086 /* Watch out for 'A ' // x vs. 'A' // x. */
2087
2088 if (op1_left->expr_type == EXPR_CONSTANT
2089 && op2_left->expr_type == EXPR_CONSTANT
2090 && op1_left->value.character.length
2091 != op2_left->value.character.length)
2092 return change;
2093 else
2094 {
2095 free (op1_left);
2096 free (op2_left);
2097 if (firstarg)
2098 {
2099 firstarg->expr = op1_right;
2100 secondarg->expr = op2_right;
2101 }
2102 else
2103 {
2104 e->value.op.op1 = op1_right;
2105 e->value.op.op2 = op2_right;
2106 }
2107 optimize_comparison (e, op);
2108 return true;
2109 }
2110 }
2111 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
2112 {
2113 free (op1_right);
2114 free (op2_right);
2115 if (firstarg)
2116 {
2117 firstarg->expr = op1_left;
2118 secondarg->expr = op2_left;
2119 }
2120 else
2121 {
2122 e->value.op.op1 = op1_left;
2123 e->value.op.op2 = op2_left;
2124 }
2125
2126 optimize_comparison (e, op);
2127 return true;
2128 }
2129 }
2130 }
2131 else
2132 {
2133 /* eq can only be -1, 0 or 1 at this point. */
2134 switch (op)
2135 {
2136 case INTRINSIC_EQ:
2137 result = eq == 0;
2138 break;
2139
2140 case INTRINSIC_GE:
2141 result = eq >= 0;
2142 break;
2143
2144 case INTRINSIC_LE:
2145 result = eq <= 0;
2146 break;
2147
2148 case INTRINSIC_NE:
2149 result = eq != 0;
2150 break;
2151
2152 case INTRINSIC_GT:
2153 result = eq > 0;
2154 break;
2155
2156 case INTRINSIC_LT:
2157 result = eq < 0;
2158 break;
2159
2160 default:
2161 gfc_internal_error ("illegal OP in optimize_comparison");
2162 break;
2163 }
2164
2165 /* Replace the expression by a constant expression. The typespec
2166 and where remains the way it is. */
2167 free (op1);
2168 free (op2);
2169 e->expr_type = EXPR_CONSTANT;
2170 e->value.logical = result;
2171 return true;
2172 }
2173 }
2174
2175 return change;
2176 }
2177
2178 /* Optimize a trim function by replacing it with an equivalent substring
2179 involving a call to len_trim. This only works for expressions where
2180 variables are trimmed. Return true if anything was modified. */
2181
2182 static bool
2183 optimize_trim (gfc_expr *e)
2184 {
2185 gfc_expr *a;
2186 gfc_ref *ref;
2187 gfc_expr *fcn;
2188 gfc_ref **rr = NULL;
2189
2190 /* Don't do this optimization within an argument list, because
2191 otherwise aliasing issues may occur. */
2192
2193 if (count_arglist != 1)
2194 return false;
2195
2196 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
2197 || e->value.function.isym == NULL
2198 || e->value.function.isym->id != GFC_ISYM_TRIM)
2199 return false;
2200
2201 a = e->value.function.actual->expr;
2202
2203 if (a->expr_type != EXPR_VARIABLE)
2204 return false;
2205
2206 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
2207
2208 if (a->symtree->n.sym->attr.allocatable)
2209 return false;
2210
2211 /* Follow all references to find the correct place to put the newly
2212 created reference. FIXME: Also handle substring references and
2213 array references. Array references cause strange regressions at
2214 the moment. */
2215
2216 if (a->ref)
2217 {
2218 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
2219 {
2220 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
2221 return false;
2222 }
2223 }
2224
2225 strip_function_call (e);
2226
2227 if (e->ref == NULL)
2228 rr = &(e->ref);
2229
2230 /* Create the reference. */
2231
2232 ref = gfc_get_ref ();
2233 ref->type = REF_SUBSTRING;
2234
2235 /* Set the start of the reference. */
2236
2237 ref->u.ss.start = gfc_get_int_expr (gfc_charlen_int_kind, NULL, 1);
2238
2239 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
2240
2241 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_charlen_int_kind);
2242
2243 /* Set the end of the reference to the call to len_trim. */
2244
2245 ref->u.ss.end = fcn;
2246 gcc_assert (rr != NULL && *rr == NULL);
2247 *rr = ref;
2248 return true;
2249 }
2250
2251 /* Optimize minloc(b), where b is rank 1 array, into
2252 (/ minloc(b, dim=1) /), and similarly for maxloc,
2253 as the latter forms are expanded inline. */
2254
2255 static void
2256 optimize_minmaxloc (gfc_expr **e)
2257 {
2258 gfc_expr *fn = *e;
2259 gfc_actual_arglist *a;
2260 char *name, *p;
2261
2262 if (fn->rank != 1
2263 || fn->value.function.actual == NULL
2264 || fn->value.function.actual->expr == NULL
2265 || fn->value.function.actual->expr->rank != 1)
2266 return;
2267
2268 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
2269 (*e)->shape = fn->shape;
2270 fn->rank = 0;
2271 fn->shape = NULL;
2272 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
2273
2274 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
2275 strcpy (name, fn->value.function.name);
2276 p = strstr (name, "loc0");
2277 p[3] = '1';
2278 fn->value.function.name = gfc_get_string ("%s", name);
2279 if (fn->value.function.actual->next)
2280 {
2281 a = fn->value.function.actual->next;
2282 gcc_assert (a->expr == NULL);
2283 }
2284 else
2285 {
2286 a = gfc_get_actual_arglist ();
2287 fn->value.function.actual->next = a;
2288 }
2289 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
2290 &fn->where);
2291 mpz_set_ui (a->expr->value.integer, 1);
2292 }
2293
2294 /* Callback function for code checking that we do not pass a DO variable to an
2295 INTENT(OUT) or INTENT(INOUT) dummy variable. */
2296
2297 static int
2298 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2299 void *data ATTRIBUTE_UNUSED)
2300 {
2301 gfc_code *co;
2302 int i;
2303 gfc_formal_arglist *f;
2304 gfc_actual_arglist *a;
2305 gfc_code *cl;
2306 do_t loop, *lp;
2307 bool seen_goto;
2308
2309 co = *c;
2310
2311 /* If the doloop_list grew, we have to truncate it here. */
2312
2313 if ((unsigned) doloop_level < doloop_list.length())
2314 doloop_list.truncate (doloop_level);
2315
2316 seen_goto = false;
2317 switch (co->op)
2318 {
2319 case EXEC_DO:
2320
2321 if (co->ext.iterator && co->ext.iterator->var)
2322 loop.c = co;
2323 else
2324 loop.c = NULL;
2325
2326 loop.branch_level = if_level + select_level;
2327 loop.seen_goto = false;
2328 doloop_list.safe_push (loop);
2329 break;
2330
2331 /* If anything could transfer control away from a suspicious
2332 subscript, make sure to set seen_goto in the current DO loop
2333 (if any). */
2334 case EXEC_GOTO:
2335 case EXEC_EXIT:
2336 case EXEC_STOP:
2337 case EXEC_ERROR_STOP:
2338 case EXEC_CYCLE:
2339 seen_goto = true;
2340 break;
2341
2342 case EXEC_OPEN:
2343 if (co->ext.open->err)
2344 seen_goto = true;
2345 break;
2346
2347 case EXEC_CLOSE:
2348 if (co->ext.close->err)
2349 seen_goto = true;
2350 break;
2351
2352 case EXEC_BACKSPACE:
2353 case EXEC_ENDFILE:
2354 case EXEC_REWIND:
2355 case EXEC_FLUSH:
2356
2357 if (co->ext.filepos->err)
2358 seen_goto = true;
2359 break;
2360
2361 case EXEC_INQUIRE:
2362 if (co->ext.filepos->err)
2363 seen_goto = true;
2364 break;
2365
2366 case EXEC_READ:
2367 case EXEC_WRITE:
2368 if (co->ext.dt->err || co->ext.dt->end || co->ext.dt->eor)
2369 seen_goto = true;
2370 break;
2371
2372 case EXEC_WAIT:
2373 if (co->ext.wait->err || co->ext.wait->end || co->ext.wait->eor)
2374 loop.seen_goto = true;
2375 break;
2376
2377 case EXEC_CALL:
2378
2379 if (co->resolved_sym == NULL)
2380 break;
2381
2382 f = gfc_sym_get_dummy_args (co->resolved_sym);
2383
2384 /* Withot a formal arglist, there is only unknown INTENT,
2385 which we don't check for. */
2386 if (f == NULL)
2387 break;
2388
2389 a = co->ext.actual;
2390
2391 while (a && f)
2392 {
2393 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2394 {
2395 gfc_symbol *do_sym;
2396 cl = lp->c;
2397
2398 if (cl == NULL)
2399 break;
2400
2401 do_sym = cl->ext.iterator->var->symtree->n.sym;
2402
2403 if (a->expr && a->expr->symtree
2404 && a->expr->symtree->n.sym == do_sym)
2405 {
2406 if (f->sym->attr.intent == INTENT_OUT)
2407 gfc_error_now ("Variable %qs at %L set to undefined "
2408 "value inside loop beginning at %L as "
2409 "INTENT(OUT) argument to subroutine %qs",
2410 do_sym->name, &a->expr->where,
2411 &(doloop_list[i].c->loc),
2412 co->symtree->n.sym->name);
2413 else if (f->sym->attr.intent == INTENT_INOUT)
2414 gfc_error_now ("Variable %qs at %L not definable inside "
2415 "loop beginning at %L as INTENT(INOUT) "
2416 "argument to subroutine %qs",
2417 do_sym->name, &a->expr->where,
2418 &(doloop_list[i].c->loc),
2419 co->symtree->n.sym->name);
2420 }
2421 }
2422 a = a->next;
2423 f = f->next;
2424 }
2425 break;
2426
2427 default:
2428 break;
2429 }
2430 if (seen_goto && doloop_level > 0)
2431 doloop_list[doloop_level-1].seen_goto = true;
2432
2433 return 0;
2434 }
2435
2436 /* Callback function to warn about different things within DO loops. */
2437
2438 static int
2439 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2440 void *data ATTRIBUTE_UNUSED)
2441 {
2442 do_t *last;
2443
2444 if (doloop_list.length () == 0)
2445 return 0;
2446
2447 if ((*e)->expr_type == EXPR_FUNCTION)
2448 do_intent (e);
2449
2450 last = &doloop_list.last();
2451 if (last->seen_goto && !warn_do_subscript)
2452 return 0;
2453
2454 if ((*e)->expr_type == EXPR_VARIABLE)
2455 do_subscript (e);
2456
2457 return 0;
2458 }
2459
2460 typedef struct
2461 {
2462 gfc_symbol *sym;
2463 mpz_t val;
2464 } insert_index_t;
2465
2466 /* Callback function - if the expression is the variable in data->sym,
2467 replace it with a constant from data->val. */
2468
2469 static int
2470 callback_insert_index (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2471 void *data)
2472 {
2473 insert_index_t *d;
2474 gfc_expr *ex, *n;
2475
2476 ex = (*e);
2477 if (ex->expr_type != EXPR_VARIABLE)
2478 return 0;
2479
2480 d = (insert_index_t *) data;
2481 if (ex->symtree->n.sym != d->sym)
2482 return 0;
2483
2484 n = gfc_get_constant_expr (BT_INTEGER, ex->ts.kind, &ex->where);
2485 mpz_set (n->value.integer, d->val);
2486
2487 gfc_free_expr (ex);
2488 *e = n;
2489 return 0;
2490 }
2491
2492 /* In the expression e, replace occurrences of the variable sym with
2493 val. If this results in a constant expression, return true and
2494 return the value in ret. Return false if the expression already
2495 is a constant. Caller has to clear ret in that case. */
2496
2497 static bool
2498 insert_index (gfc_expr *e, gfc_symbol *sym, mpz_t val, mpz_t ret)
2499 {
2500 gfc_expr *n;
2501 insert_index_t data;
2502 bool rc;
2503
2504 if (e->expr_type == EXPR_CONSTANT)
2505 return false;
2506
2507 n = gfc_copy_expr (e);
2508 data.sym = sym;
2509 mpz_init_set (data.val, val);
2510 gfc_expr_walker (&n, callback_insert_index, (void *) &data);
2511 gfc_simplify_expr (n, 0);
2512
2513 if (n->expr_type == EXPR_CONSTANT)
2514 {
2515 rc = true;
2516 mpz_init_set (ret, n->value.integer);
2517 }
2518 else
2519 rc = false;
2520
2521 mpz_clear (data.val);
2522 gfc_free_expr (n);
2523 return rc;
2524
2525 }
2526
2527 /* Check array subscripts for possible out-of-bounds accesses in DO
2528 loops with constant bounds. */
2529
2530 static int
2531 do_subscript (gfc_expr **e)
2532 {
2533 gfc_expr *v;
2534 gfc_array_ref *ar;
2535 gfc_ref *ref;
2536 int i,j;
2537 gfc_code *dl;
2538 do_t *lp;
2539
2540 v = *e;
2541 /* Constants are already checked. */
2542 if (v->expr_type == EXPR_CONSTANT)
2543 return 0;
2544
2545 /* Wrong warnings will be generated in an associate list. */
2546 if (in_assoc_list)
2547 return 0;
2548
2549 for (ref = v->ref; ref; ref = ref->next)
2550 {
2551 if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT)
2552 {
2553 ar = & ref->u.ar;
2554 FOR_EACH_VEC_ELT (doloop_list, j, lp)
2555 {
2556 gfc_symbol *do_sym;
2557 mpz_t do_start, do_step, do_end;
2558 bool have_do_start, have_do_end;
2559 bool error_not_proven;
2560 int warn;
2561
2562 dl = lp->c;
2563 if (dl == NULL)
2564 break;
2565
2566 /* If we are within a branch, or a goto or equivalent
2567 was seen in the DO loop before, then we cannot prove that
2568 this expression is actually evaluated. Don't do anything
2569 unless we want to see it all. */
2570 error_not_proven = lp->seen_goto
2571 || lp->branch_level < if_level + select_level;
2572
2573 if (error_not_proven && !warn_do_subscript)
2574 break;
2575
2576 if (error_not_proven)
2577 warn = OPT_Wdo_subscript;
2578 else
2579 warn = 0;
2580
2581 do_sym = dl->ext.iterator->var->symtree->n.sym;
2582 if (do_sym->ts.type != BT_INTEGER)
2583 continue;
2584
2585 /* If we do not know about the stepsize, the loop may be zero trip.
2586 Do not warn in this case. */
2587
2588 if (dl->ext.iterator->step->expr_type == EXPR_CONSTANT)
2589 mpz_init_set (do_step, dl->ext.iterator->step->value.integer);
2590 else
2591 continue;
2592
2593 if (dl->ext.iterator->start->expr_type == EXPR_CONSTANT)
2594 {
2595 have_do_start = true;
2596 mpz_init_set (do_start, dl->ext.iterator->start->value.integer);
2597 }
2598 else
2599 have_do_start = false;
2600
2601
2602 if (dl->ext.iterator->end->expr_type == EXPR_CONSTANT)
2603 {
2604 have_do_end = true;
2605 mpz_init_set (do_end, dl->ext.iterator->end->value.integer);
2606 }
2607 else
2608 have_do_end = false;
2609
2610 if (!have_do_start && !have_do_end)
2611 return 0;
2612
2613 /* May have to correct the end value if the step does not equal
2614 one. */
2615 if (have_do_start && have_do_end && mpz_cmp_ui (do_step, 1) != 0)
2616 {
2617 mpz_t diff, rem;
2618
2619 mpz_init (diff);
2620 mpz_init (rem);
2621 mpz_sub (diff, do_end, do_start);
2622 mpz_tdiv_r (rem, diff, do_step);
2623 mpz_sub (do_end, do_end, rem);
2624 mpz_clear (diff);
2625 mpz_clear (rem);
2626 }
2627
2628 for (i = 0; i< ar->dimen; i++)
2629 {
2630 mpz_t val;
2631 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_start
2632 && insert_index (ar->start[i], do_sym, do_start, val))
2633 {
2634 if (ar->as->lower[i]
2635 && ar->as->lower[i]->expr_type == EXPR_CONSTANT
2636 && mpz_cmp (val, ar->as->lower[i]->value.integer) < 0)
2637 gfc_warning (warn, "Array reference at %L out of bounds "
2638 "(%ld < %ld) in loop beginning at %L",
2639 &ar->start[i]->where, mpz_get_si (val),
2640 mpz_get_si (ar->as->lower[i]->value.integer),
2641 &doloop_list[j].c->loc);
2642
2643 if (ar->as->upper[i]
2644 && ar->as->upper[i]->expr_type == EXPR_CONSTANT
2645 && mpz_cmp (val, ar->as->upper[i]->value.integer) > 0)
2646 gfc_warning (warn, "Array reference at %L out of bounds "
2647 "(%ld > %ld) in loop beginning at %L",
2648 &ar->start[i]->where, mpz_get_si (val),
2649 mpz_get_si (ar->as->upper[i]->value.integer),
2650 &doloop_list[j].c->loc);
2651
2652 mpz_clear (val);
2653 }
2654
2655 if (ar->dimen_type[i] == DIMEN_ELEMENT && have_do_end
2656 && insert_index (ar->start[i], do_sym, do_end, val))
2657 {
2658 if (ar->as->lower[i]
2659 && ar->as->lower[i]->expr_type == EXPR_CONSTANT
2660 && mpz_cmp (val, ar->as->lower[i]->value.integer) < 0)
2661 gfc_warning (warn, "Array reference at %L out of bounds "
2662 "(%ld < %ld) in loop beginning at %L",
2663 &ar->start[i]->where, mpz_get_si (val),
2664 mpz_get_si (ar->as->lower[i]->value.integer),
2665 &doloop_list[j].c->loc);
2666
2667 if (ar->as->upper[i]
2668 && ar->as->upper[i]->expr_type == EXPR_CONSTANT
2669 && mpz_cmp (val, ar->as->upper[i]->value.integer) > 0)
2670 gfc_warning (warn, "Array reference at %L out of bounds "
2671 "(%ld > %ld) in loop beginning at %L",
2672 &ar->start[i]->where, mpz_get_si (val),
2673 mpz_get_si (ar->as->upper[i]->value.integer),
2674 &doloop_list[j].c->loc);
2675
2676 mpz_clear (val);
2677 }
2678 }
2679 }
2680 }
2681 }
2682 return 0;
2683 }
2684 /* Function for functions checking that we do not pass a DO variable
2685 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
2686
2687 static int
2688 do_intent (gfc_expr **e)
2689 {
2690 gfc_formal_arglist *f;
2691 gfc_actual_arglist *a;
2692 gfc_expr *expr;
2693 gfc_code *dl;
2694 do_t *lp;
2695 int i;
2696
2697 expr = *e;
2698 if (expr->expr_type != EXPR_FUNCTION)
2699 return 0;
2700
2701 /* Intrinsic functions don't modify their arguments. */
2702
2703 if (expr->value.function.isym)
2704 return 0;
2705
2706 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
2707
2708 /* Without a formal arglist, there is only unknown INTENT,
2709 which we don't check for. */
2710 if (f == NULL)
2711 return 0;
2712
2713 a = expr->value.function.actual;
2714
2715 while (a && f)
2716 {
2717 FOR_EACH_VEC_ELT (doloop_list, i, lp)
2718 {
2719 gfc_symbol *do_sym;
2720 dl = lp->c;
2721 if (dl == NULL)
2722 break;
2723
2724 do_sym = dl->ext.iterator->var->symtree->n.sym;
2725
2726 if (a->expr && a->expr->symtree
2727 && a->expr->symtree->n.sym == do_sym)
2728 {
2729 if (f->sym->attr.intent == INTENT_OUT)
2730 gfc_error_now ("Variable %qs at %L set to undefined value "
2731 "inside loop beginning at %L as INTENT(OUT) "
2732 "argument to function %qs", do_sym->name,
2733 &a->expr->where, &doloop_list[i].c->loc,
2734 expr->symtree->n.sym->name);
2735 else if (f->sym->attr.intent == INTENT_INOUT)
2736 gfc_error_now ("Variable %qs at %L not definable inside loop"
2737 " beginning at %L as INTENT(INOUT) argument to"
2738 " function %qs", do_sym->name,
2739 &a->expr->where, &doloop_list[i].c->loc,
2740 expr->symtree->n.sym->name);
2741 }
2742 }
2743 a = a->next;
2744 f = f->next;
2745 }
2746
2747 return 0;
2748 }
2749
2750 static void
2751 doloop_warn (gfc_namespace *ns)
2752 {
2753 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
2754 }
2755
2756 /* This selction deals with inlining calls to MATMUL. */
2757
2758 /* Replace calls to matmul outside of straight assignments with a temporary
2759 variable so that later inlining will work. */
2760
2761 static int
2762 matmul_to_var_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
2763 void *data)
2764 {
2765 gfc_expr *e, *n;
2766 bool *found = (bool *) data;
2767
2768 e = *ep;
2769
2770 if (e->expr_type != EXPR_FUNCTION
2771 || e->value.function.isym == NULL
2772 || e->value.function.isym->id != GFC_ISYM_MATMUL)
2773 return 0;
2774
2775 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2776 || in_where || in_assoc_list)
2777 return 0;
2778
2779 /* Check if this is already in the form c = matmul(a,b). */
2780
2781 if ((*current_code)->expr2 == e)
2782 return 0;
2783
2784 n = create_var (e, "matmul");
2785
2786 /* If create_var is unable to create a variable (for example if
2787 -fno-realloc-lhs is in force with a variable that does not have bounds
2788 known at compile-time), just return. */
2789
2790 if (n == NULL)
2791 return 0;
2792
2793 *ep = n;
2794 *found = true;
2795 return 0;
2796 }
2797
2798 /* Set current_code and associated variables so that matmul_to_var_expr can
2799 work. */
2800
2801 static int
2802 matmul_to_var_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2803 void *data ATTRIBUTE_UNUSED)
2804 {
2805 if (current_code != c)
2806 {
2807 current_code = c;
2808 inserted_block = NULL;
2809 changed_statement = NULL;
2810 }
2811
2812 return 0;
2813 }
2814
2815
2816 /* Take a statement of the shape c = matmul(a,b) and create temporaries
2817 for a and b if there is a dependency between the arguments and the
2818 result variable or if a or b are the result of calculations that cannot
2819 be handled by the inliner. */
2820
2821 static int
2822 matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
2823 void *data ATTRIBUTE_UNUSED)
2824 {
2825 gfc_expr *expr1, *expr2;
2826 gfc_code *co;
2827 gfc_actual_arglist *a, *b;
2828 bool a_tmp, b_tmp;
2829 gfc_expr *matrix_a, *matrix_b;
2830 bool conjg_a, conjg_b, transpose_a, transpose_b;
2831
2832 co = *c;
2833
2834 if (co->op != EXEC_ASSIGN)
2835 return 0;
2836
2837 if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
2838 || in_where)
2839 return 0;
2840
2841 /* This has some duplication with inline_matmul_assign. This
2842 is because the creation of temporary variables could still fail,
2843 and inline_matmul_assign still needs to be able to handle these
2844 cases. */
2845 expr1 = co->expr1;
2846 expr2 = co->expr2;
2847
2848 if (expr2->expr_type != EXPR_FUNCTION
2849 || expr2->value.function.isym == NULL
2850 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
2851 return 0;
2852
2853 a_tmp = false;
2854 a = expr2->value.function.actual;
2855 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
2856 if (matrix_a != NULL)
2857 {
2858 if (matrix_a->expr_type == EXPR_VARIABLE
2859 && (gfc_check_dependency (matrix_a, expr1, true)
2860 || has_dimen_vector_ref (matrix_a)))
2861 a_tmp = true;
2862 }
2863 else
2864 a_tmp = true;
2865
2866 b_tmp = false;
2867 b = a->next;
2868 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
2869 if (matrix_b != NULL)
2870 {
2871 if (matrix_b->expr_type == EXPR_VARIABLE
2872 && (gfc_check_dependency (matrix_b, expr1, true)
2873 || has_dimen_vector_ref (matrix_b)))
2874 b_tmp = true;
2875 }
2876 else
2877 b_tmp = true;
2878
2879 if (!a_tmp && !b_tmp)
2880 return 0;
2881
2882 current_code = c;
2883 inserted_block = NULL;
2884 changed_statement = NULL;
2885 if (a_tmp)
2886 {
2887 gfc_expr *at;
2888 at = create_var (a->expr,"mma");
2889 if (at)
2890 a->expr = at;
2891 }
2892 if (b_tmp)
2893 {
2894 gfc_expr *bt;
2895 bt = create_var (b->expr,"mmb");
2896 if (bt)
2897 b->expr = bt;
2898 }
2899 return 0;
2900 }
2901
2902 /* Auxiliary function to build and simplify an array inquiry function.
2903 dim is zero-based. */
2904
2905 static gfc_expr *
2906 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim)
2907 {
2908 gfc_expr *fcn;
2909 gfc_expr *dim_arg, *kind;
2910 const char *name;
2911 gfc_expr *ec;
2912
2913 switch (id)
2914 {
2915 case GFC_ISYM_LBOUND:
2916 name = "_gfortran_lbound";
2917 break;
2918
2919 case GFC_ISYM_UBOUND:
2920 name = "_gfortran_ubound";
2921 break;
2922
2923 case GFC_ISYM_SIZE:
2924 name = "_gfortran_size";
2925 break;
2926
2927 default:
2928 gcc_unreachable ();
2929 }
2930
2931 dim_arg = gfc_get_int_expr (gfc_default_integer_kind, &e->where, dim);
2932 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2933 gfc_index_integer_kind);
2934
2935 ec = gfc_copy_expr (e);
2936 fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3,
2937 ec, dim_arg, kind);
2938 gfc_simplify_expr (fcn, 0);
2939 return fcn;
2940 }
2941
2942 /* Builds a logical expression. */
2943
2944 static gfc_expr*
2945 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2946 {
2947 gfc_typespec ts;
2948 gfc_expr *res;
2949
2950 ts.type = BT_LOGICAL;
2951 ts.kind = gfc_default_logical_kind;
2952 res = gfc_get_expr ();
2953 res->where = e1->where;
2954 res->expr_type = EXPR_OP;
2955 res->value.op.op = op;
2956 res->value.op.op1 = e1;
2957 res->value.op.op2 = e2;
2958 res->ts = ts;
2959
2960 return res;
2961 }
2962
2963
2964 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
2965 compatible typespecs. */
2966
2967 static gfc_expr *
2968 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2969 {
2970 gfc_expr *res;
2971
2972 res = gfc_get_expr ();
2973 res->ts = e1->ts;
2974 res->where = e1->where;
2975 res->expr_type = EXPR_OP;
2976 res->value.op.op = op;
2977 res->value.op.op1 = e1;
2978 res->value.op.op2 = e2;
2979 gfc_simplify_expr (res, 0);
2980 return res;
2981 }
2982
2983 /* Generate the IF statement for a runtime check if we want to do inlining or
2984 not - putting in the code for both branches and putting it into the syntax
2985 tree is the caller's responsibility. For fixed array sizes, this should be
2986 removed by DCE. Only called for rank-two matrices A and B. */
2987
2988 static gfc_code *
2989 inline_limit_check (gfc_expr *a, gfc_expr *b, enum matrix_case m_case)
2990 {
2991 gfc_expr *inline_limit;
2992 gfc_code *if_1, *if_2, *else_2;
2993 gfc_expr *b2, *a2, *a1, *m1, *m2;
2994 gfc_typespec ts;
2995 gfc_expr *cond;
2996
2997 gcc_assert (m_case == A2B2 || m_case == A2B2T || m_case == A2TB2);
2998
2999 /* Calculation is done in real to avoid integer overflow. */
3000
3001 inline_limit = gfc_get_constant_expr (BT_REAL, gfc_default_real_kind,
3002 &a->where);
3003 mpfr_set_si (inline_limit->value.real, flag_inline_matmul_limit,
3004 GFC_RND_MODE);
3005 mpfr_pow_ui (inline_limit->value.real, inline_limit->value.real, 3,
3006 GFC_RND_MODE);
3007
3008 a1 = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3009 a2 = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
3010 b2 = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3011
3012 gfc_clear_ts (&ts);
3013 ts.type = BT_REAL;
3014 ts.kind = gfc_default_real_kind;
3015 gfc_convert_type_warn (a1, &ts, 2, 0);
3016 gfc_convert_type_warn (a2, &ts, 2, 0);
3017 gfc_convert_type_warn (b2, &ts, 2, 0);
3018
3019 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
3020 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
3021
3022 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
3023 gfc_simplify_expr (cond, 0);
3024
3025 else_2 = XCNEW (gfc_code);
3026 else_2->op = EXEC_IF;
3027 else_2->loc = a->where;
3028
3029 if_2 = XCNEW (gfc_code);
3030 if_2->op = EXEC_IF;
3031 if_2->expr1 = cond;
3032 if_2->loc = a->where;
3033 if_2->block = else_2;
3034
3035 if_1 = XCNEW (gfc_code);
3036 if_1->op = EXEC_IF;
3037 if_1->block = if_2;
3038 if_1->loc = a->where;
3039
3040 return if_1;
3041 }
3042
3043
3044 /* Insert code to issue a runtime error if the expressions are not equal. */
3045
3046 static gfc_code *
3047 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
3048 {
3049 gfc_expr *cond;
3050 gfc_code *if_1, *if_2;
3051 gfc_code *c;
3052 gfc_actual_arglist *a1, *a2, *a3;
3053
3054 gcc_assert (e1->where.lb);
3055 /* Build the call to runtime_error. */
3056 c = XCNEW (gfc_code);
3057 c->op = EXEC_CALL;
3058 c->loc = e1->where;
3059
3060 /* Get a null-terminated message string. */
3061
3062 a1 = gfc_get_actual_arglist ();
3063 a1->expr = gfc_get_character_expr (gfc_default_character_kind, &e1->where,
3064 msg, strlen(msg)+1);
3065 c->ext.actual = a1;
3066
3067 /* Pass the value of the first expression. */
3068 a2 = gfc_get_actual_arglist ();
3069 a2->expr = gfc_copy_expr (e1);
3070 a1->next = a2;
3071
3072 /* Pass the value of the second expression. */
3073 a3 = gfc_get_actual_arglist ();
3074 a3->expr = gfc_copy_expr (e2);
3075 a2->next = a3;
3076
3077 gfc_check_fe_runtime_error (c->ext.actual);
3078 gfc_resolve_fe_runtime_error (c);
3079
3080 if_2 = XCNEW (gfc_code);
3081 if_2->op = EXEC_IF;
3082 if_2->loc = e1->where;
3083 if_2->next = c;
3084
3085 if_1 = XCNEW (gfc_code);
3086 if_1->op = EXEC_IF;
3087 if_1->block = if_2;
3088 if_1->loc = e1->where;
3089
3090 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
3091 gfc_simplify_expr (cond, 0);
3092 if_2->expr1 = cond;
3093
3094 return if_1;
3095 }
3096
3097 /* Handle matrix reallocation. Caller is responsible to insert into
3098 the code tree.
3099
3100 For the two-dimensional case, build
3101
3102 if (allocated(c)) then
3103 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
3104 deallocate(c)
3105 allocate (c(size(a,1), size(b,2)))
3106 end if
3107 else
3108 allocate (c(size(a,1),size(b,2)))
3109 end if
3110
3111 and for the other cases correspondingly.
3112 */
3113
3114 static gfc_code *
3115 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
3116 enum matrix_case m_case)
3117 {
3118
3119 gfc_expr *allocated, *alloc_expr;
3120 gfc_code *if_alloc_1, *if_alloc_2, *if_size_1, *if_size_2;
3121 gfc_code *else_alloc;
3122 gfc_code *deallocate, *allocate1, *allocate_else;
3123 gfc_array_ref *ar;
3124 gfc_expr *cond, *ne1, *ne2;
3125
3126 if (warn_realloc_lhs)
3127 gfc_warning (OPT_Wrealloc_lhs,
3128 "Code for reallocating the allocatable array at %L will "
3129 "be added", &c->where);
3130
3131 alloc_expr = gfc_copy_expr (c);
3132
3133 ar = gfc_find_array_ref (alloc_expr);
3134 gcc_assert (ar && ar->type == AR_FULL);
3135
3136 /* c comes in as a full ref. Change it into a copy and make it into an
3137 element ref so it has the right form for for ALLOCATE. In the same
3138 switch statement, also generate the size comparison for the secod IF
3139 statement. */
3140
3141 ar->type = AR_ELEMENT;
3142
3143 switch (m_case)
3144 {
3145 case A2B2:
3146 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3147 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3148 ne1 = build_logical_expr (INTRINSIC_NE,
3149 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3150 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
3151 ne2 = build_logical_expr (INTRINSIC_NE,
3152 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3153 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3154 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3155 break;
3156
3157 case A2B2T:
3158 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3159 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
3160
3161 ne1 = build_logical_expr (INTRINSIC_NE,
3162 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3163 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
3164 ne2 = build_logical_expr (INTRINSIC_NE,
3165 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3166 get_array_inq_function (GFC_ISYM_SIZE, b, 1));
3167 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3168 break;
3169
3170 case A2TB2:
3171
3172 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
3173 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3174
3175 ne1 = build_logical_expr (INTRINSIC_NE,
3176 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3177 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3178 ne2 = build_logical_expr (INTRINSIC_NE,
3179 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
3180 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3181 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
3182 break;
3183
3184 case A2B1:
3185 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
3186 cond = build_logical_expr (INTRINSIC_NE,
3187 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3188 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
3189 break;
3190
3191 case A1B2:
3192 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
3193 cond = build_logical_expr (INTRINSIC_NE,
3194 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
3195 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
3196 break;
3197
3198 default:
3199 gcc_unreachable();
3200
3201 }
3202
3203 gfc_simplify_expr (cond, 0);
3204
3205 /* We need two identical allocate statements in two
3206 branches of the IF statement. */
3207
3208 allocate1 = XCNEW (gfc_code);
3209 allocate1->op = EXEC_ALLOCATE;
3210 allocate1->ext.alloc.list = gfc_get_alloc ();
3211 allocate1->loc = c->where;
3212 allocate1->ext.alloc.list->expr = gfc_copy_expr (alloc_expr);
3213
3214 allocate_else = XCNEW (gfc_code);
3215 allocate_else->op = EXEC_ALLOCATE;
3216 allocate_else->ext.alloc.list = gfc_get_alloc ();
3217 allocate_else->loc = c->where;
3218 allocate_else->ext.alloc.list->expr = alloc_expr;
3219
3220 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
3221 "_gfortran_allocated", c->where,
3222 1, gfc_copy_expr (c));
3223
3224 deallocate = XCNEW (gfc_code);
3225 deallocate->op = EXEC_DEALLOCATE;
3226 deallocate->ext.alloc.list = gfc_get_alloc ();
3227 deallocate->ext.alloc.list->expr = gfc_copy_expr (c);
3228 deallocate->next = allocate1;
3229 deallocate->loc = c->where;
3230
3231 if_size_2 = XCNEW (gfc_code);
3232 if_size_2->op = EXEC_IF;
3233 if_size_2->expr1 = cond;
3234 if_size_2->loc = c->where;
3235 if_size_2->next = deallocate;
3236
3237 if_size_1 = XCNEW (gfc_code);
3238 if_size_1->op = EXEC_IF;
3239 if_size_1->block = if_size_2;
3240 if_size_1->loc = c->where;
3241
3242 else_alloc = XCNEW (gfc_code);
3243 else_alloc->op = EXEC_IF;
3244 else_alloc->loc = c->where;
3245 else_alloc->next = allocate_else;
3246
3247 if_alloc_2 = XCNEW (gfc_code);
3248 if_alloc_2->op = EXEC_IF;
3249 if_alloc_2->expr1 = allocated;
3250 if_alloc_2->loc = c->where;
3251 if_alloc_2->next = if_size_1;
3252 if_alloc_2->block = else_alloc;
3253
3254 if_alloc_1 = XCNEW (gfc_code);
3255 if_alloc_1->op = EXEC_IF;
3256 if_alloc_1->block = if_alloc_2;
3257 if_alloc_1->loc = c->where;
3258
3259 return if_alloc_1;
3260 }
3261
3262 /* Callback function for has_function_or_op. */
3263
3264 static int
3265 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
3266 void *data ATTRIBUTE_UNUSED)
3267 {
3268 if ((*e) == 0)
3269 return 0;
3270 else
3271 return (*e)->expr_type == EXPR_FUNCTION
3272 || (*e)->expr_type == EXPR_OP;
3273 }
3274
3275 /* Returns true if the expression contains a function. */
3276
3277 static bool
3278 has_function_or_op (gfc_expr **e)
3279 {
3280 if (e == NULL)
3281 return false;
3282 else
3283 return gfc_expr_walker (e, is_function_or_op, NULL);
3284 }
3285
3286 /* Freeze (assign to a temporary variable) a single expression. */
3287
3288 static void
3289 freeze_expr (gfc_expr **ep)
3290 {
3291 gfc_expr *ne;
3292 if (has_function_or_op (ep))
3293 {
3294 ne = create_var (*ep, "freeze");
3295 *ep = ne;
3296 }
3297 }
3298
3299 /* Go through an expression's references and assign them to temporary
3300 variables if they contain functions. This is usually done prior to
3301 front-end scalarization to avoid multiple invocations of functions. */
3302
3303 static void
3304 freeze_references (gfc_expr *e)
3305 {
3306 gfc_ref *r;
3307 gfc_array_ref *ar;
3308 int i;
3309
3310 for (r=e->ref; r; r=r->next)
3311 {
3312 if (r->type == REF_SUBSTRING)
3313 {
3314 if (r->u.ss.start != NULL)
3315 freeze_expr (&r->u.ss.start);
3316
3317 if (r->u.ss.end != NULL)
3318 freeze_expr (&r->u.ss.end);
3319 }
3320 else if (r->type == REF_ARRAY)
3321 {
3322 ar = &r->u.ar;
3323 switch (ar->type)
3324 {
3325 case AR_FULL:
3326 break;
3327
3328 case AR_SECTION:
3329 for (i=0; i<ar->dimen; i++)
3330 {
3331 if (ar->dimen_type[i] == DIMEN_RANGE)
3332 {
3333 freeze_expr (&ar->start[i]);
3334 freeze_expr (&ar->end[i]);
3335 freeze_expr (&ar->stride[i]);
3336 }
3337 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
3338 {
3339 freeze_expr (&ar->start[i]);
3340 }
3341 }
3342 break;
3343
3344 case AR_ELEMENT:
3345 for (i=0; i<ar->dimen; i++)
3346 freeze_expr (&ar->start[i]);
3347 break;
3348
3349 default:
3350 break;
3351 }
3352 }
3353 }
3354 }
3355
3356 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
3357
3358 static gfc_expr *
3359 convert_to_index_kind (gfc_expr *e)
3360 {
3361 gfc_expr *res;
3362
3363 gcc_assert (e != NULL);
3364
3365 res = gfc_copy_expr (e);
3366
3367 gcc_assert (e->ts.type == BT_INTEGER);
3368
3369 if (res->ts.kind != gfc_index_integer_kind)
3370 {
3371 gfc_typespec ts;
3372 gfc_clear_ts (&ts);
3373 ts.type = BT_INTEGER;
3374 ts.kind = gfc_index_integer_kind;
3375
3376 gfc_convert_type_warn (e, &ts, 2, 0);
3377 }
3378
3379 return res;
3380 }
3381
3382 /* Function to create a DO loop including creation of the
3383 iteration variable. gfc_expr are copied.*/
3384
3385 static gfc_code *
3386 create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where,
3387 gfc_namespace *ns, char *vname)
3388 {
3389
3390 char name[GFC_MAX_SYMBOL_LEN +1];
3391 gfc_symtree *symtree;
3392 gfc_symbol *symbol;
3393 gfc_expr *i;
3394 gfc_code *n, *n2;
3395
3396 /* Create an expression for the iteration variable. */
3397 if (vname)
3398 sprintf (name, "__var_%d_do_%s", var_num++, vname);
3399 else
3400 sprintf (name, "__var_%d_do", var_num++);
3401
3402
3403 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
3404 gcc_unreachable ();
3405
3406 /* Create the loop variable. */
3407
3408 symbol = symtree->n.sym;
3409 symbol->ts.type = BT_INTEGER;
3410 symbol->ts.kind = gfc_index_integer_kind;
3411 symbol->attr.flavor = FL_VARIABLE;
3412 symbol->attr.referenced = 1;
3413 symbol->attr.dimension = 0;
3414 symbol->attr.fe_temp = 1;
3415 gfc_commit_symbol (symbol);
3416
3417 i = gfc_get_expr ();
3418 i->expr_type = EXPR_VARIABLE;
3419 i->ts = symbol->ts;
3420 i->rank = 0;
3421 i->where = *where;
3422 i->symtree = symtree;
3423
3424 /* ... and the nested DO statements. */
3425 n = XCNEW (gfc_code);
3426 n->op = EXEC_DO;
3427 n->loc = *where;
3428 n->ext.iterator = gfc_get_iterator ();
3429 n->ext.iterator->var = i;
3430 n->ext.iterator->start = convert_to_index_kind (start);
3431 n->ext.iterator->end = convert_to_index_kind (end);
3432 if (step)
3433 n->ext.iterator->step = convert_to_index_kind (step);
3434 else
3435 n->ext.iterator->step = gfc_get_int_expr (gfc_index_integer_kind,
3436 where, 1);
3437
3438 n2 = XCNEW (gfc_code);
3439 n2->op = EXEC_DO;
3440 n2->loc = *where;
3441 n2->next = NULL;
3442 n->block = n2;
3443 return n;
3444 }
3445
3446 /* Get the upper bound of the DO loops for matmul along a dimension. This
3447 is one-based. */
3448
3449 static gfc_expr*
3450 get_size_m1 (gfc_expr *e, int dimen)
3451 {
3452 mpz_t size;
3453 gfc_expr *res;
3454
3455 if (gfc_array_dimen_size (e, dimen - 1, &size))
3456 {
3457 res = gfc_get_constant_expr (BT_INTEGER,
3458 gfc_index_integer_kind, &e->where);
3459 mpz_sub_ui (res->value.integer, size, 1);
3460 mpz_clear (size);
3461 }
3462 else
3463 {
3464 res = get_operand (INTRINSIC_MINUS,
3465 get_array_inq_function (GFC_ISYM_SIZE, e, dimen),
3466 gfc_get_int_expr (gfc_index_integer_kind,
3467 &e->where, 1));
3468 gfc_simplify_expr (res, 0);
3469 }
3470
3471 return res;
3472 }
3473
3474 /* Function to return a scalarized expression. It is assumed that indices are
3475 zero based to make generation of DO loops easier. A zero as index will
3476 access the first element along a dimension. Single element references will
3477 be skipped. A NULL as an expression will be replaced by a full reference.
3478 This assumes that the index loops have gfc_index_integer_kind, and that all
3479 references have been frozen. */
3480
3481 static gfc_expr*
3482 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
3483 {
3484 gfc_array_ref *ar;
3485 int i;
3486 int rank;
3487 gfc_expr *e;
3488 int i_index;
3489 bool was_fullref;
3490
3491 e = gfc_copy_expr(e_in);
3492
3493 rank = e->rank;
3494
3495 ar = gfc_find_array_ref (e);
3496
3497 /* We scalarize count_index variables, reducing the rank by count_index. */
3498
3499 e->rank = rank - count_index;
3500
3501 was_fullref = ar->type == AR_FULL;
3502
3503 if (e->rank == 0)
3504 ar->type = AR_ELEMENT;
3505 else
3506 ar->type = AR_SECTION;
3507
3508 /* Loop over the indices. For each index, create the expression
3509 index * stride + lbound(e, dim). */
3510
3511 i_index = 0;
3512 for (i=0; i < ar->dimen; i++)
3513 {
3514 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
3515 {
3516 if (index[i_index] != NULL)
3517 {
3518 gfc_expr *lbound, *nindex;
3519 gfc_expr *loopvar;
3520
3521 loopvar = gfc_copy_expr (index[i_index]);
3522
3523 if (ar->stride[i])
3524 {
3525 gfc_expr *tmp;
3526
3527 tmp = gfc_copy_expr(ar->stride[i]);
3528 if (tmp->ts.kind != gfc_index_integer_kind)
3529 {
3530 gfc_typespec ts;
3531 gfc_clear_ts (&ts);
3532 ts.type = BT_INTEGER;
3533 ts.kind = gfc_index_integer_kind;
3534 gfc_convert_type (tmp, &ts, 2);
3535 }
3536 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
3537 }
3538 else
3539 nindex = loopvar;
3540
3541 /* Calculate the lower bound of the expression. */
3542 if (ar->start[i])
3543 {
3544 lbound = gfc_copy_expr (ar->start[i]);
3545 if (lbound->ts.kind != gfc_index_integer_kind)
3546 {
3547 gfc_typespec ts;
3548 gfc_clear_ts (&ts);
3549 ts.type = BT_INTEGER;
3550 ts.kind = gfc_index_integer_kind;
3551 gfc_convert_type (lbound, &ts, 2);
3552
3553 }
3554 }
3555 else
3556 {
3557 gfc_expr *lbound_e;
3558 gfc_ref *ref;
3559
3560 lbound_e = gfc_copy_expr (e_in);
3561
3562 for (ref = lbound_e->ref; ref; ref = ref->next)
3563 if (ref->type == REF_ARRAY
3564 && (ref->u.ar.type == AR_FULL
3565 || ref->u.ar.type == AR_SECTION))
3566 break;
3567
3568 if (ref->next)
3569 {
3570 gfc_free_ref_list (ref->next);
3571 ref->next = NULL;
3572 }
3573
3574 if (!was_fullref)
3575 {
3576 /* Look at full individual sections, like a(:). The first index
3577 is the lbound of a full ref. */
3578 int j;
3579 gfc_array_ref *ar;
3580 int to;
3581
3582 ar = &ref->u.ar;
3583
3584 /* For assumed size, we need to keep around the final
3585 reference in order not to get an error on resolution
3586 below, and we cannot use AR_FULL. */
3587
3588 if (ar->as->type == AS_ASSUMED_SIZE)
3589 {
3590 ar->type = AR_SECTION;
3591 to = ar->dimen - 1;
3592 }
3593 else
3594 {
3595 to = ar->dimen;
3596 ar->type = AR_FULL;
3597 }
3598
3599 for (j = 0; j < to; j++)
3600 {
3601 gfc_free_expr (ar->start[j]);
3602 ar->start[j] = NULL;
3603 gfc_free_expr (ar->end[j]);
3604 ar->end[j] = NULL;
3605 gfc_free_expr (ar->stride[j]);
3606 ar->stride[j] = NULL;
3607 }
3608
3609 /* We have to get rid of the shape, if there is one. Do
3610 so by freeing it and calling gfc_resolve to rebuild
3611 it, if necessary. */
3612
3613 if (lbound_e->shape)
3614 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
3615
3616 lbound_e->rank = ar->dimen;
3617 gfc_resolve_expr (lbound_e);
3618 }
3619 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
3620 i + 1);
3621 gfc_free_expr (lbound_e);
3622 }
3623
3624 ar->dimen_type[i] = DIMEN_ELEMENT;
3625
3626 gfc_free_expr (ar->start[i]);
3627 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
3628
3629 gfc_free_expr (ar->end[i]);
3630 ar->end[i] = NULL;
3631 gfc_free_expr (ar->stride[i]);
3632 ar->stride[i] = NULL;
3633 gfc_simplify_expr (ar->start[i], 0);
3634 }
3635 else if (was_fullref)
3636 {
3637 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
3638 }
3639 i_index ++;
3640 }
3641 }
3642
3643 return e;
3644 }
3645
3646 /* Helper function to check for a dimen vector as subscript. */
3647
3648 static bool
3649 has_dimen_vector_ref (gfc_expr *e)
3650 {
3651 gfc_array_ref *ar;
3652 int i;
3653
3654 ar = gfc_find_array_ref (e);
3655 gcc_assert (ar);
3656 if (ar->type == AR_FULL)
3657 return false;
3658
3659 for (i=0; i<ar->dimen; i++)
3660 if (ar->dimen_type[i] == DIMEN_VECTOR)
3661 return true;
3662
3663 return false;
3664 }
3665
3666 /* If handed an expression of the form
3667
3668 TRANSPOSE(CONJG(A))
3669
3670 check if A can be handled by matmul and return if there is an uneven number
3671 of CONJG calls. Return a pointer to the array when everything is OK, NULL
3672 otherwise. The caller has to check for the correct rank. */
3673
3674 static gfc_expr*
3675 check_conjg_transpose_variable (gfc_expr *e, bool *conjg, bool *transpose)
3676 {
3677 *conjg = false;
3678 *transpose = false;
3679
3680 do
3681 {
3682 if (e->expr_type == EXPR_VARIABLE)
3683 {
3684 gcc_assert (e->rank == 1 || e->rank == 2);
3685 return e;
3686 }
3687 else if (e->expr_type == EXPR_FUNCTION)
3688 {
3689 if (e->value.function.isym == NULL)
3690 return NULL;
3691
3692 if (e->value.function.isym->id == GFC_ISYM_CONJG)
3693 *conjg = !*conjg;
3694 else if (e->value.function.isym->id == GFC_ISYM_TRANSPOSE)
3695 *transpose = !*transpose;
3696 else return NULL;
3697 }
3698 else
3699 return NULL;
3700
3701 e = e->value.function.actual->expr;
3702 }
3703 while(1);
3704
3705 return NULL;
3706 }
3707
3708 /* Inline assignments of the form c = matmul(a,b).
3709 Handle only the cases currently where b and c are rank-two arrays.
3710
3711 This basically translates the code to
3712
3713 BLOCK
3714 integer i,j,k
3715 c = 0
3716 do j=0, size(b,2)-1
3717 do k=0, size(a, 2)-1
3718 do i=0, size(a, 1)-1
3719 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
3720 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
3721 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
3722 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
3723 end do
3724 end do
3725 end do
3726 END BLOCK
3727
3728 */
3729
3730 static int
3731 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
3732 void *data ATTRIBUTE_UNUSED)
3733 {
3734 gfc_code *co = *c;
3735 gfc_expr *expr1, *expr2;
3736 gfc_expr *matrix_a, *matrix_b;
3737 gfc_actual_arglist *a, *b;
3738 gfc_code *do_1, *do_2, *do_3, *assign_zero, *assign_matmul;
3739 gfc_expr *zero_e;
3740 gfc_expr *u1, *u2, *u3;
3741 gfc_expr *list[2];
3742 gfc_expr *ascalar, *bscalar, *cscalar;
3743 gfc_expr *mult;
3744 gfc_expr *var_1, *var_2, *var_3;
3745 gfc_expr *zero;
3746 gfc_namespace *ns;
3747 gfc_intrinsic_op op_times, op_plus;
3748 enum matrix_case m_case;
3749 int i;
3750 gfc_code *if_limit = NULL;
3751 gfc_code **next_code_point;
3752 bool conjg_a, conjg_b, transpose_a, transpose_b;
3753
3754 if (co->op != EXEC_ASSIGN)
3755 return 0;
3756
3757 if (in_where || in_assoc_list)
3758 return 0;
3759
3760 /* The BLOCKS generated for the temporary variables and FORALL don't
3761 mix. */
3762 if (forall_level > 0)
3763 return 0;
3764
3765 /* For now don't do anything in OpenMP workshare, it confuses
3766 its translation, which expects only the allowed statements in there.
3767 We should figure out how to parallelize this eventually. */
3768 if (in_omp_workshare)
3769 return 0;
3770
3771 expr1 = co->expr1;
3772 expr2 = co->expr2;
3773 if (expr2->expr_type != EXPR_FUNCTION
3774 || expr2->value.function.isym == NULL
3775 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
3776 return 0;
3777
3778 current_code = c;
3779 inserted_block = NULL;
3780 changed_statement = NULL;
3781
3782 a = expr2->value.function.actual;
3783 matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
3784 if (matrix_a == NULL)
3785 return 0;
3786
3787 b = a->next;
3788 matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
3789 if (matrix_b == NULL)
3790 return 0;
3791
3792 if (has_dimen_vector_ref (expr1) || has_dimen_vector_ref (matrix_a)
3793 || has_dimen_vector_ref (matrix_b))
3794 return 0;
3795
3796 /* We do not handle data dependencies yet. */
3797 if (gfc_check_dependency (expr1, matrix_a, true)
3798 || gfc_check_dependency (expr1, matrix_b, true))
3799 return 0;
3800
3801 m_case = none;
3802 if (matrix_a->rank == 2)
3803 {
3804 if (transpose_a)
3805 {
3806 if (matrix_b->rank == 2 && !transpose_b)
3807 m_case = A2TB2;
3808 }
3809 else
3810 {
3811 if (matrix_b->rank == 1)
3812 m_case = A2B1;
3813 else /* matrix_b->rank == 2 */
3814 {
3815 if (transpose_b)
3816 m_case = A2B2T;
3817 else
3818 m_case = A2B2;
3819 }
3820 }
3821 }
3822 else /* matrix_a->rank == 1 */
3823 {
3824 if (matrix_b->rank == 2)
3825 {
3826 if (!transpose_b)
3827 m_case = A1B2;
3828 }
3829 }
3830
3831 if (m_case == none)
3832 return 0;
3833
3834 ns = insert_block ();
3835
3836 /* Assign the type of the zero expression for initializing the resulting
3837 array, and the expression (+ and * for real, integer and complex;
3838 .and. and .or for logical. */
3839
3840 switch(expr1->ts.type)
3841 {
3842 case BT_INTEGER:
3843 zero_e = gfc_get_int_expr (expr1->ts.kind, &expr1->where, 0);
3844 op_times = INTRINSIC_TIMES;
3845 op_plus = INTRINSIC_PLUS;
3846 break;
3847
3848 case BT_LOGICAL:
3849 op_times = INTRINSIC_AND;
3850 op_plus = INTRINSIC_OR;
3851 zero_e = gfc_get_logical_expr (expr1->ts.kind, &expr1->where,
3852 0);
3853 break;
3854 case BT_REAL:
3855 zero_e = gfc_get_constant_expr (BT_REAL, expr1->ts.kind,
3856 &expr1->where);
3857 mpfr_set_si (zero_e->value.real, 0, GFC_RND_MODE);
3858 op_times = INTRINSIC_TIMES;
3859 op_plus = INTRINSIC_PLUS;
3860 break;
3861
3862 case BT_COMPLEX:
3863 zero_e = gfc_get_constant_expr (BT_COMPLEX, expr1->ts.kind,
3864 &expr1->where);
3865 mpc_set_si_si (zero_e->value.complex, 0, 0, GFC_RND_MODE);
3866 op_times = INTRINSIC_TIMES;
3867 op_plus = INTRINSIC_PLUS;
3868
3869 break;
3870
3871 default:
3872 gcc_unreachable();
3873 }
3874
3875 current_code = &ns->code;
3876
3877 /* Freeze the references, keeping track of how many temporary variables were
3878 created. */
3879 n_vars = 0;
3880 freeze_references (matrix_a);
3881 freeze_references (matrix_b);
3882 freeze_references (expr1);
3883
3884 if (n_vars == 0)
3885 next_code_point = current_code;
3886 else
3887 {
3888 next_code_point = &ns->code;
3889 for (i=0; i<n_vars; i++)
3890 next_code_point = &(*next_code_point)->next;
3891 }
3892
3893 /* Take care of the inline flag. If the limit check evaluates to a
3894 constant, dead code elimination will eliminate the unneeded branch. */
3895
3896 if (m_case == A2B2 && flag_inline_matmul_limit > 0)
3897 {
3898 if_limit = inline_limit_check (matrix_a, matrix_b, m_case);
3899
3900 /* Insert the original statement into the else branch. */
3901 if_limit->block->block->next = co;
3902 co->next = NULL;
3903
3904 /* ... and the new ones go into the original one. */
3905 *next_code_point = if_limit;
3906 next_code_point = &if_limit->block->next;
3907 }
3908
3909 assign_zero = XCNEW (gfc_code);
3910 assign_zero->op = EXEC_ASSIGN;
3911 assign_zero->loc = co->loc;
3912 assign_zero->expr1 = gfc_copy_expr (expr1);
3913 assign_zero->expr2 = zero_e;
3914
3915 /* Handle the reallocation, if needed. */
3916 if (flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1))
3917 {
3918 gfc_code *lhs_alloc;
3919
3920 /* Only need to check a single dimension for the A2B2 case for
3921 bounds checking, the rest will be allocated. Also check this
3922 for A2B1. */
3923
3924 if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && (m_case == A2B2 || m_case == A2B1))
3925 {
3926 gfc_code *test;
3927 gfc_expr *a2, *b1;
3928
3929 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3930 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3931 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
3932 "in MATMUL intrinsic: Is %ld, should be %ld");
3933 *next_code_point = test;
3934 next_code_point = &test->next;
3935 }
3936
3937
3938 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
3939
3940 *next_code_point = lhs_alloc;
3941 next_code_point = &lhs_alloc->next;
3942
3943 }
3944 else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
3945 {
3946 gfc_code *test;
3947 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
3948
3949 if (m_case == A2B2 || m_case == A2B1)
3950 {
3951 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
3952 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3953 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
3954 "in MATMUL intrinsic: Is %ld, should be %ld");
3955 *next_code_point = test;
3956 next_code_point = &test->next;
3957
3958 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3959 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3960
3961 if (m_case == A2B2)
3962 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3963 "MATMUL intrinsic for dimension 1: "
3964 "is %ld, should be %ld");
3965 else if (m_case == A2B1)
3966 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
3967 "MATMUL intrinsic: "
3968 "is %ld, should be %ld");
3969
3970
3971 *next_code_point = test;
3972 next_code_point = &test->next;
3973 }
3974 else if (m_case == A1B2)
3975 {
3976 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
3977 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
3978 test = runtime_error_ne (b1, a1, "Dimension of array B incorrect "
3979 "in MATMUL intrinsic: Is %ld, should be %ld");
3980 *next_code_point = test;
3981 next_code_point = &test->next;
3982
3983 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
3984 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3985
3986 test = runtime_error_ne (c1, b2, "Incorrect extent in return array in "
3987 "MATMUL intrinsic: "
3988 "is %ld, should be %ld");
3989
3990 *next_code_point = test;
3991 next_code_point = &test->next;
3992 }
3993
3994 if (m_case == A2B2)
3995 {
3996 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
3997 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
3998 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
3999 "MATMUL intrinsic for dimension 2: is %ld, should be %ld");
4000
4001 *next_code_point = test;
4002 next_code_point = &test->next;
4003 }
4004
4005 if (m_case == A2B2T)
4006 {
4007 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4008 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4009 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
4010 "MATMUL intrinsic for dimension 1: "
4011 "is %ld, should be %ld");
4012
4013 *next_code_point = test;
4014 next_code_point = &test->next;
4015
4016 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4017 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4018 test = runtime_error_ne (c2, b1, "Incorrect extent in return array in "
4019 "MATMUL intrinsic for dimension 2: "
4020 "is %ld, should be %ld");
4021 *next_code_point = test;
4022 next_code_point = &test->next;
4023
4024 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4025 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4026
4027 test = runtime_error_ne (b2, a2, "Incorrect extent in argument B in "
4028 "MATMUL intrnisic for dimension 2: "
4029 "is %ld, should be %ld");
4030 *next_code_point = test;
4031 next_code_point = &test->next;
4032
4033 }
4034
4035 if (m_case == A2TB2)
4036 {
4037 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
4038 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
4039
4040 test = runtime_error_ne (c1, a2, "Incorrect extent in return array in "
4041 "MATMUL intrinsic for dimension 1: "
4042 "is %ld, should be %ld");
4043
4044 *next_code_point = test;
4045 next_code_point = &test->next;
4046
4047 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
4048 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
4049 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
4050 "MATMUL intrinsic for dimension 2: "
4051 "is %ld, should be %ld");
4052 *next_code_point = test;
4053 next_code_point = &test->next;
4054
4055 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
4056 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
4057
4058 test = runtime_error_ne (b1, a1, "Incorrect extent in argument B in "
4059 "MATMUL intrnisic for dimension 2: "
4060 "is %ld, should be %ld");
4061 *next_code_point = test;
4062 next_code_point = &test->next;
4063
4064 }
4065 }
4066
4067 *next_code_point = assign_zero;
4068
4069 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
4070
4071 assign_matmul = XCNEW (gfc_code);
4072 assign_matmul->op = EXEC_ASSIGN;
4073 assign_matmul->loc = co->loc;
4074
4075 /* Get the bounds for the loops, create them and create the scalarized
4076 expressions. */
4077
4078 switch (m_case)
4079 {
4080 case A2B2:
4081 inline_limit_check (matrix_a, matrix_b, m_case);
4082
4083 u1 = get_size_m1 (matrix_b, 2);
4084 u2 = get_size_m1 (matrix_a, 2);
4085 u3 = get_size_m1 (matrix_a, 1);
4086
4087 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4088 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4089 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4090
4091 do_1->block->next = do_2;
4092 do_2->block->next = do_3;
4093 do_3->block->next = assign_matmul;
4094
4095 var_1 = do_1->ext.iterator->var;
4096 var_2 = do_2->ext.iterator->var;
4097 var_3 = do_3->ext.iterator->var;
4098
4099 list[0] = var_3;
4100 list[1] = var_1;
4101 cscalar = scalarized_expr (co->expr1, list, 2);
4102
4103 list[0] = var_3;
4104 list[1] = var_2;
4105 ascalar = scalarized_expr (matrix_a, list, 2);
4106
4107 list[0] = var_2;
4108 list[1] = var_1;
4109 bscalar = scalarized_expr (matrix_b, list, 2);
4110
4111 break;
4112
4113 case A2B2T:
4114 inline_limit_check (matrix_a, matrix_b, m_case);
4115
4116 u1 = get_size_m1 (matrix_b, 1);
4117 u2 = get_size_m1 (matrix_a, 2);
4118 u3 = get_size_m1 (matrix_a, 1);
4119
4120 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4121 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4122 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4123
4124 do_1->block->next = do_2;
4125 do_2->block->next = do_3;
4126 do_3->block->next = assign_matmul;
4127
4128 var_1 = do_1->ext.iterator->var;
4129 var_2 = do_2->ext.iterator->var;
4130 var_3 = do_3->ext.iterator->var;
4131
4132 list[0] = var_3;
4133 list[1] = var_1;
4134 cscalar = scalarized_expr (co->expr1, list, 2);
4135
4136 list[0] = var_3;
4137 list[1] = var_2;
4138 ascalar = scalarized_expr (matrix_a, list, 2);
4139
4140 list[0] = var_1;
4141 list[1] = var_2;
4142 bscalar = scalarized_expr (matrix_b, list, 2);
4143
4144 break;
4145
4146 case A2TB2:
4147 inline_limit_check (matrix_a, matrix_b, m_case);
4148
4149 u1 = get_size_m1 (matrix_a, 2);
4150 u2 = get_size_m1 (matrix_b, 2);
4151 u3 = get_size_m1 (matrix_a, 1);
4152
4153 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4154 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4155 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
4156
4157 do_1->block->next = do_2;
4158 do_2->block->next = do_3;
4159 do_3->block->next = assign_matmul;
4160
4161 var_1 = do_1->ext.iterator->var;
4162 var_2 = do_2->ext.iterator->var;
4163 var_3 = do_3->ext.iterator->var;
4164
4165 list[0] = var_1;
4166 list[1] = var_2;
4167 cscalar = scalarized_expr (co->expr1, list, 2);
4168
4169 list[0] = var_3;
4170 list[1] = var_1;
4171 ascalar = scalarized_expr (matrix_a, list, 2);
4172
4173 list[0] = var_3;
4174 list[1] = var_2;
4175 bscalar = scalarized_expr (matrix_b, list, 2);
4176
4177 break;
4178
4179 case A2B1:
4180 u1 = get_size_m1 (matrix_b, 1);
4181 u2 = get_size_m1 (matrix_a, 1);
4182
4183 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4184 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4185
4186 do_1->block->next = do_2;
4187 do_2->block->next = assign_matmul;
4188
4189 var_1 = do_1->ext.iterator->var;
4190 var_2 = do_2->ext.iterator->var;
4191
4192 list[0] = var_2;
4193 cscalar = scalarized_expr (co->expr1, list, 1);
4194
4195 list[0] = var_2;
4196 list[1] = var_1;
4197 ascalar = scalarized_expr (matrix_a, list, 2);
4198
4199 list[0] = var_1;
4200 bscalar = scalarized_expr (matrix_b, list, 1);
4201
4202 break;
4203
4204 case A1B2:
4205 u1 = get_size_m1 (matrix_b, 2);
4206 u2 = get_size_m1 (matrix_a, 1);
4207
4208 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
4209 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
4210
4211 do_1->block->next = do_2;
4212 do_2->block->next = assign_matmul;
4213
4214 var_1 = do_1->ext.iterator->var;
4215 var_2 = do_2->ext.iterator->var;
4216
4217 list[0] = var_1;
4218 cscalar = scalarized_expr (co->expr1, list, 1);
4219
4220 list[0] = var_2;
4221 ascalar = scalarized_expr (matrix_a, list, 1);
4222
4223 list[0] = var_2;
4224 list[1] = var_1;
4225 bscalar = scalarized_expr (matrix_b, list, 2);
4226
4227 break;
4228
4229 default:
4230 gcc_unreachable();
4231 }
4232
4233 /* Build the conjg call around the variables. Set the typespec manually
4234 because gfc_build_intrinsic_call sometimes gets this wrong. */
4235 if (conjg_a)
4236 {
4237 gfc_typespec ts;
4238 ts = matrix_a->ts;
4239 ascalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
4240 matrix_a->where, 1, ascalar);
4241 ascalar->ts = ts;
4242 }
4243
4244 if (conjg_b)
4245 {
4246 gfc_typespec ts;
4247 ts = matrix_b->ts;
4248 bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
4249 matrix_b->where, 1, bscalar);
4250 bscalar->ts = ts;
4251 }
4252 /* First loop comes after the zero assignment. */
4253 assign_zero->next = do_1;
4254
4255 /* Build the assignment expression in the loop. */
4256 assign_matmul->expr1 = gfc_copy_expr (cscalar);
4257
4258 mult = get_operand (op_times, ascalar, bscalar);
4259 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
4260
4261 /* If we don't want to keep the original statement around in
4262 the else branch, we can free it. */
4263
4264 if (if_limit == NULL)
4265 gfc_free_statements(co);
4266 else
4267 co->next = NULL;
4268
4269 gfc_free_expr (zero);
4270 *walk_subtrees = 0;
4271 return 0;
4272 }
4273
4274
4275 /* Code for index interchange for loops which are grouped together in DO
4276 CONCURRENT or FORALL statements. This is currently only applied if the
4277 iterations are grouped together in a single statement.
4278
4279 For this transformation, it is assumed that memory access in strides is
4280 expensive, and that loops which access later indices (which access memory
4281 in bigger strides) should be moved to the first loops.
4282
4283 For this, a loop over all the statements is executed, counting the times
4284 that the loop iteration values are accessed in each index. The loop
4285 indices are then sorted to minimize access to later indices from inner
4286 loops. */
4287
4288 /* Type for holding index information. */
4289
4290 typedef struct {
4291 gfc_symbol *sym;
4292 gfc_forall_iterator *fa;
4293 int num;
4294 int n[GFC_MAX_DIMENSIONS];
4295 } ind_type;
4296
4297 /* Callback function to determine if an expression is the
4298 corresponding variable. */
4299
4300 static int
4301 has_var (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
4302 {
4303 gfc_expr *expr = *e;
4304 gfc_symbol *sym;
4305
4306 if (expr->expr_type != EXPR_VARIABLE)
4307 return 0;
4308
4309 sym = (gfc_symbol *) data;
4310 return sym == expr->symtree->n.sym;
4311 }
4312
4313 /* Callback function to calculate the cost of a certain index. */
4314
4315 static int
4316 index_cost (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
4317 void *data)
4318 {
4319 ind_type *ind;
4320 gfc_expr *expr;
4321 gfc_array_ref *ar;
4322 gfc_ref *ref;
4323 int i,j;
4324
4325 expr = *e;
4326 if (expr->expr_type != EXPR_VARIABLE)
4327 return 0;
4328
4329 ar = NULL;
4330 for (ref = expr->ref; ref; ref = ref->next)
4331 {
4332 if (ref->type == REF_ARRAY)
4333 {
4334 ar = &ref->u.ar;
4335 break;
4336 }
4337 }
4338 if (ar == NULL || ar->type != AR_ELEMENT)
4339 return 0;
4340
4341 ind = (ind_type *) data;
4342 for (i = 0; i < ar->dimen; i++)
4343 {
4344 for (j=0; ind[j].sym != NULL; j++)
4345 {
4346 if (gfc_expr_walker (&ar->start[i], has_var, (void *) (ind[j].sym)))
4347 ind[j].n[i]++;
4348 }
4349 }
4350 return 0;
4351 }
4352
4353 /* Callback function for qsort, to sort the loop indices. */
4354
4355 static int
4356 loop_comp (const void *e1, const void *e2)
4357 {
4358 const ind_type *i1 = (const ind_type *) e1;
4359 const ind_type *i2 = (const ind_type *) e2;
4360 int i;
4361
4362 for (i=GFC_MAX_DIMENSIONS-1; i >= 0; i--)
4363 {
4364 if (i1->n[i] != i2->n[i])
4365 return i1->n[i] - i2->n[i];
4366 }
4367 /* All other things being equal, let's not change the ordering. */
4368 return i2->num - i1->num;
4369 }
4370
4371 /* Main function to do the index interchange. */
4372
4373 static int
4374 index_interchange (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
4375 void *data ATTRIBUTE_UNUSED)
4376 {
4377 gfc_code *co;
4378 co = *c;
4379 int n_iter;
4380 gfc_forall_iterator *fa;
4381 ind_type *ind;
4382 int i, j;
4383
4384 if (co->op != EXEC_FORALL && co->op != EXEC_DO_CONCURRENT)
4385 return 0;
4386
4387 n_iter = 0;
4388 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4389 n_iter ++;
4390
4391 /* Nothing to reorder. */
4392 if (n_iter < 2)
4393 return 0;
4394
4395 ind = XALLOCAVEC (ind_type, n_iter + 1);
4396
4397 i = 0;
4398 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4399 {
4400 ind[i].sym = fa->var->symtree->n.sym;
4401 ind[i].fa = fa;
4402 for (j=0; j<GFC_MAX_DIMENSIONS; j++)
4403 ind[i].n[j] = 0;
4404 ind[i].num = i;
4405 i++;
4406 }
4407 ind[n_iter].sym = NULL;
4408 ind[n_iter].fa = NULL;
4409
4410 gfc_code_walker (c, gfc_dummy_code_callback, index_cost, (void *) ind);
4411 qsort ((void *) ind, n_iter, sizeof (ind_type), loop_comp);
4412
4413 /* Do the actual index interchange. */
4414 co->ext.forall_iterator = fa = ind[0].fa;
4415 for (i=1; i<n_iter; i++)
4416 {
4417 fa->next = ind[i].fa;
4418 fa = fa->next;
4419 }
4420 fa->next = NULL;
4421
4422 if (flag_warn_frontend_loop_interchange)
4423 {
4424 for (i=1; i<n_iter; i++)
4425 {
4426 if (ind[i-1].num > ind[i].num)
4427 {
4428 gfc_warning (OPT_Wfrontend_loop_interchange,
4429 "Interchanging loops at %L", &co->loc);
4430 break;
4431 }
4432 }
4433 }
4434
4435 return 0;
4436 }
4437
4438 #define WALK_SUBEXPR(NODE) \
4439 do \
4440 { \
4441 result = gfc_expr_walker (&(NODE), exprfn, data); \
4442 if (result) \
4443 return result; \
4444 } \
4445 while (0)
4446 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
4447
4448 /* Walk expression *E, calling EXPRFN on each expression in it. */
4449
4450 int
4451 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
4452 {
4453 while (*e)
4454 {
4455 int walk_subtrees = 1;
4456 gfc_actual_arglist *a;
4457 gfc_ref *r;
4458 gfc_constructor *c;
4459
4460 int result = exprfn (e, &walk_subtrees, data);
4461 if (result)
4462 return result;
4463 if (walk_subtrees)
4464 switch ((*e)->expr_type)
4465 {
4466 case EXPR_OP:
4467 WALK_SUBEXPR ((*e)->value.op.op1);
4468 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
4469 break;
4470 case EXPR_FUNCTION:
4471 for (a = (*e)->value.function.actual; a; a = a->next)
4472 WALK_SUBEXPR (a->expr);
4473 break;
4474 case EXPR_COMPCALL:
4475 case EXPR_PPC:
4476 WALK_SUBEXPR ((*e)->value.compcall.base_object);
4477 for (a = (*e)->value.compcall.actual; a; a = a->next)
4478 WALK_SUBEXPR (a->expr);
4479 break;
4480
4481 case EXPR_STRUCTURE:
4482 case EXPR_ARRAY:
4483 for (c = gfc_constructor_first ((*e)->value.constructor); c;
4484 c = gfc_constructor_next (c))
4485 {
4486 if (c->iterator == NULL)
4487 WALK_SUBEXPR (c->expr);
4488 else
4489 {
4490 iterator_level ++;
4491 WALK_SUBEXPR (c->expr);
4492 iterator_level --;
4493 WALK_SUBEXPR (c->iterator->var);
4494 WALK_SUBEXPR (c->iterator->start);
4495 WALK_SUBEXPR (c->iterator->end);
4496 WALK_SUBEXPR (c->iterator->step);
4497 }
4498 }
4499
4500 if ((*e)->expr_type != EXPR_ARRAY)
4501 break;
4502
4503 /* Fall through to the variable case in order to walk the
4504 reference. */
4505 gcc_fallthrough ();
4506
4507 case EXPR_SUBSTRING:
4508 case EXPR_VARIABLE:
4509 for (r = (*e)->ref; r; r = r->next)
4510 {
4511 gfc_array_ref *ar;
4512 int i;
4513
4514 switch (r->type)
4515 {
4516 case REF_ARRAY:
4517 ar = &r->u.ar;
4518 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
4519 {
4520 for (i=0; i< ar->dimen; i++)
4521 {
4522 WALK_SUBEXPR (ar->start[i]);
4523 WALK_SUBEXPR (ar->end[i]);
4524 WALK_SUBEXPR (ar->stride[i]);
4525 }
4526 }
4527
4528 break;
4529
4530 case REF_SUBSTRING:
4531 WALK_SUBEXPR (r->u.ss.start);
4532 WALK_SUBEXPR (r->u.ss.end);
4533 break;
4534
4535 case REF_COMPONENT:
4536 break;
4537 }
4538 }
4539
4540 default:
4541 break;
4542 }
4543 return 0;
4544 }
4545 return 0;
4546 }
4547
4548 #define WALK_SUBCODE(NODE) \
4549 do \
4550 { \
4551 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
4552 if (result) \
4553 return result; \
4554 } \
4555 while (0)
4556
4557 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
4558 on each expression in it. If any of the hooks returns non-zero, that
4559 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
4560 no subcodes or subexpressions are traversed. */
4561
4562 int
4563 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
4564 void *data)
4565 {
4566 for (; *c; c = &(*c)->next)
4567 {
4568 int walk_subtrees = 1;
4569 int result = codefn (c, &walk_subtrees, data);
4570 if (result)
4571 return result;
4572
4573 if (walk_subtrees)
4574 {
4575 gfc_code *b;
4576 gfc_actual_arglist *a;
4577 gfc_code *co;
4578 gfc_association_list *alist;
4579 bool saved_in_omp_workshare;
4580 bool saved_in_where;
4581
4582 /* There might be statement insertions before the current code,
4583 which must not affect the expression walker. */
4584
4585 co = *c;
4586 saved_in_omp_workshare = in_omp_workshare;
4587 saved_in_where = in_where;
4588
4589 switch (co->op)
4590 {
4591
4592 case EXEC_BLOCK:
4593 WALK_SUBCODE (co->ext.block.ns->code);
4594 if (co->ext.block.assoc)
4595 {
4596 bool saved_in_assoc_list = in_assoc_list;
4597
4598 in_assoc_list = true;
4599 for (alist = co->ext.block.assoc; alist; alist = alist->next)
4600 WALK_SUBEXPR (alist->target);
4601
4602 in_assoc_list = saved_in_assoc_list;
4603 }
4604
4605 break;
4606
4607 case EXEC_DO:
4608 doloop_level ++;
4609 WALK_SUBEXPR (co->ext.iterator->var);
4610 WALK_SUBEXPR (co->ext.iterator->start);
4611 WALK_SUBEXPR (co->ext.iterator->end);
4612 WALK_SUBEXPR (co->ext.iterator->step);
4613 break;
4614
4615 case EXEC_IF:
4616 if_level ++;
4617 break;
4618
4619 case EXEC_WHERE:
4620 in_where = true;
4621 break;
4622
4623 case EXEC_CALL:
4624 case EXEC_ASSIGN_CALL:
4625 for (a = co->ext.actual; a; a = a->next)
4626 WALK_SUBEXPR (a->expr);
4627 break;
4628
4629 case EXEC_CALL_PPC:
4630 WALK_SUBEXPR (co->expr1);
4631 for (a = co->ext.actual; a; a = a->next)
4632 WALK_SUBEXPR (a->expr);
4633 break;
4634
4635 case EXEC_SELECT:
4636 WALK_SUBEXPR (co->expr1);
4637 select_level ++;
4638 for (b = co->block; b; b = b->block)
4639 {
4640 gfc_case *cp;
4641 for (cp = b->ext.block.case_list; cp; cp = cp->next)
4642 {
4643 WALK_SUBEXPR (cp->low);
4644 WALK_SUBEXPR (cp->high);
4645 }
4646 WALK_SUBCODE (b->next);
4647 }
4648 continue;
4649
4650 case EXEC_ALLOCATE:
4651 case EXEC_DEALLOCATE:
4652 {
4653 gfc_alloc *a;
4654 for (a = co->ext.alloc.list; a; a = a->next)
4655 WALK_SUBEXPR (a->expr);
4656 break;
4657 }
4658
4659 case EXEC_FORALL:
4660 case EXEC_DO_CONCURRENT:
4661 {
4662 gfc_forall_iterator *fa;
4663 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
4664 {
4665 WALK_SUBEXPR (fa->var);
4666 WALK_SUBEXPR (fa->start);
4667 WALK_SUBEXPR (fa->end);
4668 WALK_SUBEXPR (fa->stride);
4669 }
4670 if (co->op == EXEC_FORALL)
4671 forall_level ++;
4672 break;
4673 }
4674
4675 case EXEC_OPEN:
4676 WALK_SUBEXPR (co->ext.open->unit);
4677 WALK_SUBEXPR (co->ext.open->file);
4678 WALK_SUBEXPR (co->ext.open->status);
4679 WALK_SUBEXPR (co->ext.open->access);
4680 WALK_SUBEXPR (co->ext.open->form);
4681 WALK_SUBEXPR (co->ext.open->recl);
4682 WALK_SUBEXPR (co->ext.open->blank);
4683 WALK_SUBEXPR (co->ext.open->position);
4684 WALK_SUBEXPR (co->ext.open->action);
4685 WALK_SUBEXPR (co->ext.open->delim);
4686 WALK_SUBEXPR (co->ext.open->pad);
4687 WALK_SUBEXPR (co->ext.open->iostat);
4688 WALK_SUBEXPR (co->ext.open->iomsg);
4689 WALK_SUBEXPR (co->ext.open->convert);
4690 WALK_SUBEXPR (co->ext.open->decimal);
4691 WALK_SUBEXPR (co->ext.open->encoding);
4692 WALK_SUBEXPR (co->ext.open->round);
4693 WALK_SUBEXPR (co->ext.open->sign);
4694 WALK_SUBEXPR (co->ext.open->asynchronous);
4695 WALK_SUBEXPR (co->ext.open->id);
4696 WALK_SUBEXPR (co->ext.open->newunit);
4697 WALK_SUBEXPR (co->ext.open->share);
4698 WALK_SUBEXPR (co->ext.open->cc);
4699 break;
4700
4701 case EXEC_CLOSE:
4702 WALK_SUBEXPR (co->ext.close->unit);
4703 WALK_SUBEXPR (co->ext.close->status);
4704 WALK_SUBEXPR (co->ext.close->iostat);
4705 WALK_SUBEXPR (co->ext.close->iomsg);
4706 break;
4707
4708 case EXEC_BACKSPACE:
4709 case EXEC_ENDFILE:
4710 case EXEC_REWIND:
4711 case EXEC_FLUSH:
4712 WALK_SUBEXPR (co->ext.filepos->unit);
4713 WALK_SUBEXPR (co->ext.filepos->iostat);
4714 WALK_SUBEXPR (co->ext.filepos->iomsg);
4715 break;
4716
4717 case EXEC_INQUIRE:
4718 WALK_SUBEXPR (co->ext.inquire->unit);
4719 WALK_SUBEXPR (co->ext.inquire->file);
4720 WALK_SUBEXPR (co->ext.inquire->iomsg);
4721 WALK_SUBEXPR (co->ext.inquire->iostat);
4722 WALK_SUBEXPR (co->ext.inquire->exist);
4723 WALK_SUBEXPR (co->ext.inquire->opened);
4724 WALK_SUBEXPR (co->ext.inquire->number);
4725 WALK_SUBEXPR (co->ext.inquire->named);
4726 WALK_SUBEXPR (co->ext.inquire->name);
4727 WALK_SUBEXPR (co->ext.inquire->access);
4728 WALK_SUBEXPR (co->ext.inquire->sequential);
4729 WALK_SUBEXPR (co->ext.inquire->direct);
4730 WALK_SUBEXPR (co->ext.inquire->form);
4731 WALK_SUBEXPR (co->ext.inquire->formatted);
4732 WALK_SUBEXPR (co->ext.inquire->unformatted);
4733 WALK_SUBEXPR (co->ext.inquire->recl);
4734 WALK_SUBEXPR (co->ext.inquire->nextrec);
4735 WALK_SUBEXPR (co->ext.inquire->blank);
4736 WALK_SUBEXPR (co->ext.inquire->position);
4737 WALK_SUBEXPR (co->ext.inquire->action);
4738 WALK_SUBEXPR (co->ext.inquire->read);
4739 WALK_SUBEXPR (co->ext.inquire->write);
4740 WALK_SUBEXPR (co->ext.inquire->readwrite);
4741 WALK_SUBEXPR (co->ext.inquire->delim);
4742 WALK_SUBEXPR (co->ext.inquire->encoding);
4743 WALK_SUBEXPR (co->ext.inquire->pad);
4744 WALK_SUBEXPR (co->ext.inquire->iolength);
4745 WALK_SUBEXPR (co->ext.inquire->convert);
4746 WALK_SUBEXPR (co->ext.inquire->strm_pos);
4747 WALK_SUBEXPR (co->ext.inquire->asynchronous);
4748 WALK_SUBEXPR (co->ext.inquire->decimal);
4749 WALK_SUBEXPR (co->ext.inquire->pending);
4750 WALK_SUBEXPR (co->ext.inquire->id);
4751 WALK_SUBEXPR (co->ext.inquire->sign);
4752 WALK_SUBEXPR (co->ext.inquire->size);
4753 WALK_SUBEXPR (co->ext.inquire->round);
4754 break;
4755
4756 case EXEC_WAIT:
4757 WALK_SUBEXPR (co->ext.wait->unit);
4758 WALK_SUBEXPR (co->ext.wait->iostat);
4759 WALK_SUBEXPR (co->ext.wait->iomsg);
4760 WALK_SUBEXPR (co->ext.wait->id);
4761 break;
4762
4763 case EXEC_READ:
4764 case EXEC_WRITE:
4765 WALK_SUBEXPR (co->ext.dt->io_unit);
4766 WALK_SUBEXPR (co->ext.dt->format_expr);
4767 WALK_SUBEXPR (co->ext.dt->rec);
4768 WALK_SUBEXPR (co->ext.dt->advance);
4769 WALK_SUBEXPR (co->ext.dt->iostat);
4770 WALK_SUBEXPR (co->ext.dt->size);
4771 WALK_SUBEXPR (co->ext.dt->iomsg);
4772 WALK_SUBEXPR (co->ext.dt->id);
4773 WALK_SUBEXPR (co->ext.dt->pos);
4774 WALK_SUBEXPR (co->ext.dt->asynchronous);
4775 WALK_SUBEXPR (co->ext.dt->blank);
4776 WALK_SUBEXPR (co->ext.dt->decimal);
4777 WALK_SUBEXPR (co->ext.dt->delim);
4778 WALK_SUBEXPR (co->ext.dt->pad);
4779 WALK_SUBEXPR (co->ext.dt->round);
4780 WALK_SUBEXPR (co->ext.dt->sign);
4781 WALK_SUBEXPR (co->ext.dt->extra_comma);
4782 break;
4783
4784 case EXEC_OMP_PARALLEL:
4785 case EXEC_OMP_PARALLEL_DO:
4786 case EXEC_OMP_PARALLEL_DO_SIMD:
4787 case EXEC_OMP_PARALLEL_SECTIONS:
4788
4789 in_omp_workshare = false;
4790
4791 /* This goto serves as a shortcut to avoid code
4792 duplication or a larger if or switch statement. */
4793 goto check_omp_clauses;
4794
4795 case EXEC_OMP_WORKSHARE:
4796 case EXEC_OMP_PARALLEL_WORKSHARE:
4797
4798 in_omp_workshare = true;
4799
4800 /* Fall through */
4801
4802 case EXEC_OMP_CRITICAL:
4803 case EXEC_OMP_DISTRIBUTE:
4804 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
4805 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
4806 case EXEC_OMP_DISTRIBUTE_SIMD:
4807 case EXEC_OMP_DO:
4808 case EXEC_OMP_DO_SIMD:
4809 case EXEC_OMP_ORDERED:
4810 case EXEC_OMP_SECTIONS:
4811 case EXEC_OMP_SINGLE:
4812 case EXEC_OMP_END_SINGLE:
4813 case EXEC_OMP_SIMD:
4814 case EXEC_OMP_TASKLOOP:
4815 case EXEC_OMP_TASKLOOP_SIMD:
4816 case EXEC_OMP_TARGET:
4817 case EXEC_OMP_TARGET_DATA:
4818 case EXEC_OMP_TARGET_ENTER_DATA:
4819 case EXEC_OMP_TARGET_EXIT_DATA:
4820 case EXEC_OMP_TARGET_PARALLEL:
4821 case EXEC_OMP_TARGET_PARALLEL_DO:
4822 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD:
4823 case EXEC_OMP_TARGET_SIMD:
4824 case EXEC_OMP_TARGET_TEAMS:
4825 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
4826 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
4827 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4828 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
4829 case EXEC_OMP_TARGET_UPDATE:
4830 case EXEC_OMP_TASK:
4831 case EXEC_OMP_TEAMS:
4832 case EXEC_OMP_TEAMS_DISTRIBUTE:
4833 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
4834 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
4835 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
4836
4837 /* Come to this label only from the
4838 EXEC_OMP_PARALLEL_* cases above. */
4839
4840 check_omp_clauses:
4841
4842 if (co->ext.omp_clauses)
4843 {
4844 gfc_omp_namelist *n;
4845 static int list_types[]
4846 = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
4847 OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
4848 size_t idx;
4849 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
4850 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
4851 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
4852 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
4853 WALK_SUBEXPR (co->ext.omp_clauses->safelen_expr);
4854 WALK_SUBEXPR (co->ext.omp_clauses->simdlen_expr);
4855 WALK_SUBEXPR (co->ext.omp_clauses->num_teams);
4856 WALK_SUBEXPR (co->ext.omp_clauses->device);
4857 WALK_SUBEXPR (co->ext.omp_clauses->thread_limit);
4858 WALK_SUBEXPR (co->ext.omp_clauses->dist_chunk_size);
4859 WALK_SUBEXPR (co->ext.omp_clauses->grainsize);
4860 WALK_SUBEXPR (co->ext.omp_clauses->hint);
4861 WALK_SUBEXPR (co->ext.omp_clauses->num_tasks);
4862 WALK_SUBEXPR (co->ext.omp_clauses->priority);
4863 for (idx = 0; idx < OMP_IF_LAST; idx++)
4864 WALK_SUBEXPR (co->ext.omp_clauses->if_exprs[idx]);
4865 for (idx = 0;
4866 idx < sizeof (list_types) / sizeof (list_types[0]);
4867 idx++)
4868 for (n = co->ext.omp_clauses->lists[list_types[idx]];
4869 n; n = n->next)
4870 WALK_SUBEXPR (n->expr);
4871 }
4872 break;
4873 default:
4874 break;
4875 }
4876
4877 WALK_SUBEXPR (co->expr1);
4878 WALK_SUBEXPR (co->expr2);
4879 WALK_SUBEXPR (co->expr3);
4880 WALK_SUBEXPR (co->expr4);
4881 for (b = co->block; b; b = b->block)
4882 {
4883 WALK_SUBEXPR (b->expr1);
4884 WALK_SUBEXPR (b->expr2);
4885 WALK_SUBCODE (b->next);
4886 }
4887
4888 if (co->op == EXEC_FORALL)
4889 forall_level --;
4890
4891 if (co->op == EXEC_DO)
4892 doloop_level --;
4893
4894 if (co->op == EXEC_IF)
4895 if_level --;
4896
4897 if (co->op == EXEC_SELECT)
4898 select_level --;
4899
4900 in_omp_workshare = saved_in_omp_workshare;
4901 in_where = saved_in_where;
4902 }
4903 }
4904 return 0;
4905 }