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