]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/fortran/frontend-passes.c
re PR fortran/66041 (Matmul ICE)
[thirdparty/gcc.git] / gcc / fortran / frontend-passes.c
1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2015 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 "gfortran.h"
25 #include "arith.h"
26 #include "flags.h"
27 #include "dependency.h"
28 #include "constructor.h"
29 #include "opts.h"
30 #include "intrinsic.h"
31
32 /* Forward declarations. */
33
34 static void strip_function_call (gfc_expr *);
35 static void optimize_namespace (gfc_namespace *);
36 static void optimize_assignment (gfc_code *);
37 static bool optimize_op (gfc_expr *);
38 static bool optimize_comparison (gfc_expr *, gfc_intrinsic_op);
39 static bool optimize_trim (gfc_expr *);
40 static bool optimize_lexical_comparison (gfc_expr *);
41 static void optimize_minmaxloc (gfc_expr **);
42 static bool is_empty_string (gfc_expr *e);
43 static void doloop_warn (gfc_namespace *);
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 inline_matmul_assign (gfc_code **, int *, void *);
49 static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *,
50 locus *, gfc_namespace *,
51 char *vname=NULL);
52
53 /* How deep we are inside an argument list. */
54
55 static int count_arglist;
56
57 /* Vector of gfc_expr ** we operate on. */
58
59 static vec<gfc_expr **> expr_array;
60
61 /* Pointer to the gfc_code we currently work on - to be able to insert
62 a block before the statement. */
63
64 static gfc_code **current_code;
65
66 /* Pointer to the block to be inserted, and the statement we are
67 changing within the block. */
68
69 static gfc_code *inserted_block, **changed_statement;
70
71 /* The namespace we are currently dealing with. */
72
73 static gfc_namespace *current_ns;
74
75 /* If we are within any forall loop. */
76
77 static int forall_level;
78
79 /* Keep track of whether we are within an OMP workshare. */
80
81 static bool in_omp_workshare;
82
83 /* Keep track of iterators for array constructors. */
84
85 static int iterator_level;
86
87 /* Keep track of DO loop levels. */
88
89 static vec<gfc_code *> doloop_list;
90
91 static int doloop_level;
92
93 /* Vector of gfc_expr * to keep track of DO loops. */
94
95 struct my_struct *evec;
96
97 /* Keep track of association lists. */
98
99 static bool in_assoc_list;
100
101 /* Counter for temporary variables. */
102
103 static int var_num = 1;
104
105 /* What sort of matrix we are dealing with when inlining MATMUL. */
106
107 enum matrix_case { none=0, A2B2, A2B1, A1B2 };
108
109 /* Keep track of the number of expressions we have inserted so far
110 using create_var. */
111
112 int n_vars;
113
114 /* Entry point - run all passes for a namespace. */
115
116 void
117 gfc_run_passes (gfc_namespace *ns)
118 {
119
120 /* Warn about dubious DO loops where the index might
121 change. */
122
123 doloop_level = 0;
124 doloop_warn (ns);
125 doloop_list.release ();
126
127 if (flag_frontend_optimize)
128 {
129 optimize_namespace (ns);
130 optimize_reduction (ns);
131 if (flag_dump_fortran_optimized)
132 gfc_dump_parse_tree (ns, stdout);
133
134 expr_array.release ();
135 }
136
137 if (flag_realloc_lhs)
138 realloc_strings (ns);
139 }
140
141 /* Callback for each gfc_code node invoked from check_realloc_strings.
142 For an allocatable LHS string which also appears as a variable on
143 the RHS, replace
144
145 a = a(x:y)
146
147 with
148
149 tmp = a(x:y)
150 a = tmp
151 */
152
153 static int
154 realloc_string_callback (gfc_code **c, int *walk_subtrees,
155 void *data ATTRIBUTE_UNUSED)
156 {
157 gfc_expr *expr1, *expr2;
158 gfc_code *co = *c;
159 gfc_expr *n;
160
161 *walk_subtrees = 0;
162 if (co->op != EXEC_ASSIGN)
163 return 0;
164
165 expr1 = co->expr1;
166 if (expr1->ts.type != BT_CHARACTER || expr1->rank != 0
167 || !expr1->symtree->n.sym->attr.allocatable)
168 return 0;
169
170 expr2 = gfc_discard_nops (co->expr2);
171 if (expr2->expr_type != EXPR_VARIABLE)
172 return 0;
173
174 if (!gfc_check_dependency (expr1, expr2, true))
175 return 0;
176
177 current_code = c;
178 n = create_var (expr2, "trim");
179 co->expr2 = n;
180 return 0;
181 }
182
183 /* Callback for each gfc_code node invoked through gfc_code_walker
184 from optimize_namespace. */
185
186 static int
187 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
188 void *data ATTRIBUTE_UNUSED)
189 {
190
191 gfc_exec_op op;
192
193 op = (*c)->op;
194
195 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
196 || op == EXEC_CALL_PPC)
197 count_arglist = 1;
198 else
199 count_arglist = 0;
200
201 current_code = c;
202 inserted_block = NULL;
203 changed_statement = NULL;
204
205 if (op == EXEC_ASSIGN)
206 optimize_assignment (*c);
207 return 0;
208 }
209
210 /* Callback for each gfc_expr node invoked through gfc_code_walker
211 from optimize_namespace. */
212
213 static int
214 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
215 void *data ATTRIBUTE_UNUSED)
216 {
217 bool function_expr;
218
219 if ((*e)->expr_type == EXPR_FUNCTION)
220 {
221 count_arglist ++;
222 function_expr = true;
223 }
224 else
225 function_expr = false;
226
227 if (optimize_trim (*e))
228 gfc_simplify_expr (*e, 0);
229
230 if (optimize_lexical_comparison (*e))
231 gfc_simplify_expr (*e, 0);
232
233 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
234 gfc_simplify_expr (*e, 0);
235
236 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
237 switch ((*e)->value.function.isym->id)
238 {
239 case GFC_ISYM_MINLOC:
240 case GFC_ISYM_MAXLOC:
241 optimize_minmaxloc (e);
242 break;
243 default:
244 break;
245 }
246
247 if (function_expr)
248 count_arglist --;
249
250 return 0;
251 }
252
253 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
254 function is a scalar, just copy it; otherwise returns the new element, the
255 old one can be freed. */
256
257 static gfc_expr *
258 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
259 {
260 gfc_expr *fcn, *e = c->expr;
261
262 fcn = gfc_copy_expr (e);
263 if (c->iterator)
264 {
265 gfc_constructor_base newbase;
266 gfc_expr *new_expr;
267 gfc_constructor *new_c;
268
269 newbase = NULL;
270 new_expr = gfc_get_expr ();
271 new_expr->expr_type = EXPR_ARRAY;
272 new_expr->ts = e->ts;
273 new_expr->where = e->where;
274 new_expr->rank = 1;
275 new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
276 new_c->iterator = c->iterator;
277 new_expr->value.constructor = newbase;
278 c->iterator = NULL;
279
280 fcn = new_expr;
281 }
282
283 if (fcn->rank != 0)
284 {
285 gfc_isym_id id = fn->value.function.isym->id;
286
287 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
288 fcn = gfc_build_intrinsic_call (current_ns, id,
289 fn->value.function.isym->name,
290 fn->where, 3, fcn, NULL, NULL);
291 else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
292 fcn = gfc_build_intrinsic_call (current_ns, id,
293 fn->value.function.isym->name,
294 fn->where, 2, fcn, NULL);
295 else
296 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
297
298 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
299 }
300
301 return fcn;
302 }
303
304 /* Callback function for optimzation of reductions to scalars. Transform ANY
305 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
306 correspondingly. Handly only the simple cases without MASK and DIM. */
307
308 static int
309 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
310 void *data ATTRIBUTE_UNUSED)
311 {
312 gfc_expr *fn, *arg;
313 gfc_intrinsic_op op;
314 gfc_isym_id id;
315 gfc_actual_arglist *a;
316 gfc_actual_arglist *dim;
317 gfc_constructor *c;
318 gfc_expr *res, *new_expr;
319 gfc_actual_arglist *mask;
320
321 fn = *e;
322
323 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
324 || fn->value.function.isym == NULL)
325 return 0;
326
327 id = fn->value.function.isym->id;
328
329 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
330 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
331 return 0;
332
333 a = fn->value.function.actual;
334
335 /* Don't handle MASK or DIM. */
336
337 dim = a->next;
338
339 if (dim->expr != NULL)
340 return 0;
341
342 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
343 {
344 mask = dim->next;
345 if ( mask->expr != NULL)
346 return 0;
347 }
348
349 arg = a->expr;
350
351 if (arg->expr_type != EXPR_ARRAY)
352 return 0;
353
354 switch (id)
355 {
356 case GFC_ISYM_SUM:
357 op = INTRINSIC_PLUS;
358 break;
359
360 case GFC_ISYM_PRODUCT:
361 op = INTRINSIC_TIMES;
362 break;
363
364 case GFC_ISYM_ANY:
365 op = INTRINSIC_OR;
366 break;
367
368 case GFC_ISYM_ALL:
369 op = INTRINSIC_AND;
370 break;
371
372 default:
373 return 0;
374 }
375
376 c = gfc_constructor_first (arg->value.constructor);
377
378 /* Don't do any simplififcation if we have
379 - no element in the constructor or
380 - only have a single element in the array which contains an
381 iterator. */
382
383 if (c == NULL)
384 return 0;
385
386 res = copy_walk_reduction_arg (c, fn);
387
388 c = gfc_constructor_next (c);
389 while (c)
390 {
391 new_expr = gfc_get_expr ();
392 new_expr->ts = fn->ts;
393 new_expr->expr_type = EXPR_OP;
394 new_expr->rank = fn->rank;
395 new_expr->where = fn->where;
396 new_expr->value.op.op = op;
397 new_expr->value.op.op1 = res;
398 new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
399 res = new_expr;
400 c = gfc_constructor_next (c);
401 }
402
403 gfc_simplify_expr (res, 0);
404 *e = res;
405 gfc_free_expr (fn);
406
407 return 0;
408 }
409
410 /* Callback function for common function elimination, called from cfe_expr_0.
411 Put all eligible function expressions into expr_array. */
412
413 static int
414 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
415 void *data ATTRIBUTE_UNUSED)
416 {
417
418 if ((*e)->expr_type != EXPR_FUNCTION)
419 return 0;
420
421 /* We don't do character functions with unknown charlens. */
422 if ((*e)->ts.type == BT_CHARACTER
423 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
424 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
425 return 0;
426
427 /* We don't do function elimination within FORALL statements, it can
428 lead to wrong-code in certain circumstances. */
429
430 if (forall_level > 0)
431 return 0;
432
433 /* Function elimination inside an iterator could lead to functions which
434 depend on iterator variables being moved outside. FIXME: We should check
435 if the functions do indeed depend on the iterator variable. */
436
437 if (iterator_level > 0)
438 return 0;
439
440 /* If we don't know the shape at compile time, we create an allocatable
441 temporary variable to hold the intermediate result, but only if
442 allocation on assignment is active. */
443
444 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
445 return 0;
446
447 /* Skip the test for pure functions if -faggressive-function-elimination
448 is specified. */
449 if ((*e)->value.function.esym)
450 {
451 /* Don't create an array temporary for elemental functions. */
452 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
453 return 0;
454
455 /* Only eliminate potentially impure functions if the
456 user specifically requested it. */
457 if (!flag_aggressive_function_elimination
458 && !(*e)->value.function.esym->attr.pure
459 && !(*e)->value.function.esym->attr.implicit_pure)
460 return 0;
461 }
462
463 if ((*e)->value.function.isym)
464 {
465 /* Conversions are handled on the fly by the middle end,
466 transpose during trans-* stages and TRANSFER by the middle end. */
467 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
468 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
469 || gfc_inline_intrinsic_function_p (*e))
470 return 0;
471
472 /* Don't create an array temporary for elemental functions,
473 as this would be wasteful of memory.
474 FIXME: Create a scalar temporary during scalarization. */
475 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
476 return 0;
477
478 if (!(*e)->value.function.isym->pure)
479 return 0;
480 }
481
482 expr_array.safe_push (e);
483 return 0;
484 }
485
486 /* Auxiliary function to check if an expression is a temporary created by
487 create var. */
488
489 static bool
490 is_fe_temp (gfc_expr *e)
491 {
492 if (e->expr_type != EXPR_VARIABLE)
493 return false;
494
495 return e->symtree->n.sym->attr.fe_temp;
496 }
497
498 /* Determine the length of a string, if it can be evaluated as a constant
499 expression. Return a newly allocated gfc_expr or NULL on failure.
500 If the user specified a substring which is potentially longer than
501 the string itself, the string will be padded with spaces, which
502 is harmless. */
503
504 static gfc_expr *
505 constant_string_length (gfc_expr *e)
506 {
507
508 gfc_expr *length;
509 gfc_ref *ref;
510 gfc_expr *res;
511 mpz_t value;
512
513 if (e->ts.u.cl)
514 {
515 length = e->ts.u.cl->length;
516 if (length && length->expr_type == EXPR_CONSTANT)
517 return gfc_copy_expr(length);
518 }
519
520 /* Return length of substring, if constant. */
521 for (ref = e->ref; ref; ref = ref->next)
522 {
523 if (ref->type == REF_SUBSTRING
524 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
525 {
526 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
527 &e->where);
528
529 mpz_add_ui (res->value.integer, value, 1);
530 mpz_clear (value);
531 return res;
532 }
533 }
534
535 /* Return length of char symbol, if constant. */
536
537 if (e->symtree->n.sym->ts.u.cl && e->symtree->n.sym->ts.u.cl->length
538 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
539 return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length);
540
541 return NULL;
542
543 }
544
545 /* Insert a block at the current position unless it has already
546 been inserted; in this case use the one already there. */
547
548 static gfc_namespace*
549 insert_block ()
550 {
551 gfc_namespace *ns;
552
553 /* If the block hasn't already been created, do so. */
554 if (inserted_block == NULL)
555 {
556 inserted_block = XCNEW (gfc_code);
557 inserted_block->op = EXEC_BLOCK;
558 inserted_block->loc = (*current_code)->loc;
559 ns = gfc_build_block_ns (current_ns);
560 inserted_block->ext.block.ns = ns;
561 inserted_block->ext.block.assoc = NULL;
562
563 ns->code = *current_code;
564
565 /* If the statement has a label, make sure it is transferred to
566 the newly created block. */
567
568 if ((*current_code)->here)
569 {
570 inserted_block->here = (*current_code)->here;
571 (*current_code)->here = NULL;
572 }
573
574 inserted_block->next = (*current_code)->next;
575 changed_statement = &(inserted_block->ext.block.ns->code);
576 (*current_code)->next = NULL;
577 /* Insert the BLOCK at the right position. */
578 *current_code = inserted_block;
579 ns->parent = current_ns;
580 }
581 else
582 ns = inserted_block->ext.block.ns;
583
584 return ns;
585 }
586
587 /* Returns a new expression (a variable) to be used in place of the old one,
588 with an optional assignment statement before the current statement to set
589 the value of the variable. Creates a new BLOCK for the statement if that
590 hasn't already been done and puts the statement, plus the newly created
591 variables, in that block. Special cases: If the expression is constant or
592 a temporary which has already been created, just copy it. */
593
594 static gfc_expr*
595 create_var (gfc_expr * e, const char *vname)
596 {
597 char name[GFC_MAX_SYMBOL_LEN +1];
598 gfc_symtree *symtree;
599 gfc_symbol *symbol;
600 gfc_expr *result;
601 gfc_code *n;
602 gfc_namespace *ns;
603 int i;
604
605 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
606 return gfc_copy_expr (e);
607
608 ns = insert_block ();
609
610 if (vname)
611 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d_%s", var_num++, vname);
612 else
613 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d", var_num++);
614
615 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
616 gcc_unreachable ();
617
618 symbol = symtree->n.sym;
619 symbol->ts = e->ts;
620
621 if (e->rank > 0)
622 {
623 symbol->as = gfc_get_array_spec ();
624 symbol->as->rank = e->rank;
625
626 if (e->shape == NULL)
627 {
628 /* We don't know the shape at compile time, so we use an
629 allocatable. */
630 symbol->as->type = AS_DEFERRED;
631 symbol->attr.allocatable = 1;
632 }
633 else
634 {
635 symbol->as->type = AS_EXPLICIT;
636 /* Copy the shape. */
637 for (i=0; i<e->rank; i++)
638 {
639 gfc_expr *p, *q;
640
641 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
642 &(e->where));
643 mpz_set_si (p->value.integer, 1);
644 symbol->as->lower[i] = p;
645
646 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
647 &(e->where));
648 mpz_set (q->value.integer, e->shape[i]);
649 symbol->as->upper[i] = q;
650 }
651 }
652 }
653
654 if (e->ts.type == BT_CHARACTER && e->rank == 0)
655 {
656 gfc_expr *length;
657
658 length = constant_string_length (e);
659 if (length)
660 {
661 symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
662 symbol->ts.u.cl->length = length;
663 }
664 else
665 symbol->attr.allocatable = 1;
666 }
667
668 symbol->attr.flavor = FL_VARIABLE;
669 symbol->attr.referenced = 1;
670 symbol->attr.dimension = e->rank > 0;
671 symbol->attr.fe_temp = 1;
672 gfc_commit_symbol (symbol);
673
674 result = gfc_get_expr ();
675 result->expr_type = EXPR_VARIABLE;
676 result->ts = e->ts;
677 result->rank = e->rank;
678 result->shape = gfc_copy_shape (e->shape, e->rank);
679 result->symtree = symtree;
680 result->where = e->where;
681 if (e->rank > 0)
682 {
683 result->ref = gfc_get_ref ();
684 result->ref->type = REF_ARRAY;
685 result->ref->u.ar.type = AR_FULL;
686 result->ref->u.ar.where = e->where;
687 result->ref->u.ar.dimen = e->rank;
688 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
689 ? CLASS_DATA (symbol)->as : symbol->as;
690 if (warn_array_temporaries)
691 gfc_warning (OPT_Warray_temporaries,
692 "Creating array temporary at %L", &(e->where));
693 }
694
695 /* Generate the new assignment. */
696 n = XCNEW (gfc_code);
697 n->op = EXEC_ASSIGN;
698 n->loc = (*current_code)->loc;
699 n->next = *changed_statement;
700 n->expr1 = gfc_copy_expr (result);
701 n->expr2 = e;
702 *changed_statement = n;
703 n_vars ++;
704
705 return result;
706 }
707
708 /* Warn about function elimination. */
709
710 static void
711 do_warn_function_elimination (gfc_expr *e)
712 {
713 if (e->expr_type != EXPR_FUNCTION)
714 return;
715 if (e->value.function.esym)
716 gfc_warning (0, "Removing call to function %qs at %L",
717 e->value.function.esym->name, &(e->where));
718 else if (e->value.function.isym)
719 gfc_warning (0, "Removing call to function %qs at %L",
720 e->value.function.isym->name, &(e->where));
721 }
722 /* Callback function for the code walker for doing common function
723 elimination. This builds up the list of functions in the expression
724 and goes through them to detect duplicates, which it then replaces
725 by variables. */
726
727 static int
728 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
729 void *data ATTRIBUTE_UNUSED)
730 {
731 int i,j;
732 gfc_expr *newvar;
733 gfc_expr **ei, **ej;
734
735 /* Don't do this optimization within OMP workshare. */
736
737 if (in_omp_workshare)
738 {
739 *walk_subtrees = 0;
740 return 0;
741 }
742
743 expr_array.release ();
744
745 gfc_expr_walker (e, cfe_register_funcs, NULL);
746
747 /* Walk through all the functions. */
748
749 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
750 {
751 /* Skip if the function has been replaced by a variable already. */
752 if ((*ei)->expr_type == EXPR_VARIABLE)
753 continue;
754
755 newvar = NULL;
756 for (j=0; j<i; j++)
757 {
758 ej = expr_array[j];
759 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
760 {
761 if (newvar == NULL)
762 newvar = create_var (*ei, "fcn");
763
764 if (warn_function_elimination)
765 do_warn_function_elimination (*ej);
766
767 free (*ej);
768 *ej = gfc_copy_expr (newvar);
769 }
770 }
771 if (newvar)
772 *ei = newvar;
773 }
774
775 /* We did all the necessary walking in this function. */
776 *walk_subtrees = 0;
777 return 0;
778 }
779
780 /* Callback function for common function elimination, called from
781 gfc_code_walker. This keeps track of the current code, in order
782 to insert statements as needed. */
783
784 static int
785 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
786 {
787 current_code = c;
788 inserted_block = NULL;
789 changed_statement = NULL;
790
791 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
792 and allocation on assigment are prohibited inside WHERE, and finally
793 masking an expression would lead to wrong-code when replacing
794
795 WHERE (a>0)
796 b = sum(foo(a) + foo(a))
797 END WHERE
798
799 with
800
801 WHERE (a > 0)
802 tmp = foo(a)
803 b = sum(tmp + tmp)
804 END WHERE
805 */
806
807 if ((*c)->op == EXEC_WHERE)
808 {
809 *walk_subtrees = 0;
810 return 0;
811 }
812
813
814 return 0;
815 }
816
817 /* Dummy function for expression call back, for use when we
818 really don't want to do any walking. */
819
820 static int
821 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
822 void *data ATTRIBUTE_UNUSED)
823 {
824 *walk_subtrees = 0;
825 return 0;
826 }
827
828 /* Dummy function for code callback, for use when we really
829 don't want to do anything. */
830 int
831 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
832 int *walk_subtrees ATTRIBUTE_UNUSED,
833 void *data ATTRIBUTE_UNUSED)
834 {
835 return 0;
836 }
837
838 /* Code callback function for converting
839 do while(a)
840 end do
841 into the equivalent
842 do
843 if (.not. a) exit
844 end do
845 This is because common function elimination would otherwise place the
846 temporary variables outside the loop. */
847
848 static int
849 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
850 void *data ATTRIBUTE_UNUSED)
851 {
852 gfc_code *co = *c;
853 gfc_code *c_if1, *c_if2, *c_exit;
854 gfc_code *loopblock;
855 gfc_expr *e_not, *e_cond;
856
857 if (co->op != EXEC_DO_WHILE)
858 return 0;
859
860 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
861 return 0;
862
863 e_cond = co->expr1;
864
865 /* Generate the condition of the if statement, which is .not. the original
866 statement. */
867 e_not = gfc_get_expr ();
868 e_not->ts = e_cond->ts;
869 e_not->where = e_cond->where;
870 e_not->expr_type = EXPR_OP;
871 e_not->value.op.op = INTRINSIC_NOT;
872 e_not->value.op.op1 = e_cond;
873
874 /* Generate the EXIT statement. */
875 c_exit = XCNEW (gfc_code);
876 c_exit->op = EXEC_EXIT;
877 c_exit->ext.which_construct = co;
878 c_exit->loc = co->loc;
879
880 /* Generate the IF statement. */
881 c_if2 = XCNEW (gfc_code);
882 c_if2->op = EXEC_IF;
883 c_if2->expr1 = e_not;
884 c_if2->next = c_exit;
885 c_if2->loc = co->loc;
886
887 /* ... plus the one to chain it to. */
888 c_if1 = XCNEW (gfc_code);
889 c_if1->op = EXEC_IF;
890 c_if1->block = c_if2;
891 c_if1->loc = co->loc;
892
893 /* Make the DO WHILE loop into a DO block by replacing the condition
894 with a true constant. */
895 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
896
897 /* Hang the generated if statement into the loop body. */
898
899 loopblock = co->block->next;
900 co->block->next = c_if1;
901 c_if1->next = loopblock;
902
903 return 0;
904 }
905
906 /* Code callback function for converting
907 if (a) then
908 ...
909 else if (b) then
910 end if
911
912 into
913 if (a) then
914 else
915 if (b) then
916 end if
917 end if
918
919 because otherwise common function elimination would place the BLOCKs
920 into the wrong place. */
921
922 static int
923 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
924 void *data ATTRIBUTE_UNUSED)
925 {
926 gfc_code *co = *c;
927 gfc_code *c_if1, *c_if2, *else_stmt;
928
929 if (co->op != EXEC_IF)
930 return 0;
931
932 /* This loop starts out with the first ELSE statement. */
933 else_stmt = co->block->block;
934
935 while (else_stmt != NULL)
936 {
937 gfc_code *next_else;
938
939 /* If there is no condition, we're done. */
940 if (else_stmt->expr1 == NULL)
941 break;
942
943 next_else = else_stmt->block;
944
945 /* Generate the new IF statement. */
946 c_if2 = XCNEW (gfc_code);
947 c_if2->op = EXEC_IF;
948 c_if2->expr1 = else_stmt->expr1;
949 c_if2->next = else_stmt->next;
950 c_if2->loc = else_stmt->loc;
951 c_if2->block = next_else;
952
953 /* ... plus the one to chain it to. */
954 c_if1 = XCNEW (gfc_code);
955 c_if1->op = EXEC_IF;
956 c_if1->block = c_if2;
957 c_if1->loc = else_stmt->loc;
958
959 /* Insert the new IF after the ELSE. */
960 else_stmt->expr1 = NULL;
961 else_stmt->next = c_if1;
962 else_stmt->block = NULL;
963
964 else_stmt = next_else;
965 }
966 /* Don't walk subtrees. */
967 return 0;
968 }
969
970 /* Optimize a namespace, including all contained namespaces. */
971
972 static void
973 optimize_namespace (gfc_namespace *ns)
974 {
975 gfc_namespace *saved_ns = gfc_current_ns;
976 current_ns = ns;
977 gfc_current_ns = ns;
978 forall_level = 0;
979 iterator_level = 0;
980 in_assoc_list = false;
981 in_omp_workshare = false;
982
983 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
984 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
985 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
986 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
987 if (flag_inline_matmul_limit != 0)
988 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
989 NULL);
990
991 /* BLOCKs are handled in the expression walker below. */
992 for (ns = ns->contained; ns; ns = ns->sibling)
993 {
994 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
995 optimize_namespace (ns);
996 }
997 gfc_current_ns = saved_ns;
998 }
999
1000 /* Handle dependencies for allocatable strings which potentially redefine
1001 themselves in an assignment. */
1002
1003 static void
1004 realloc_strings (gfc_namespace *ns)
1005 {
1006 current_ns = ns;
1007 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1008
1009 for (ns = ns->contained; ns; ns = ns->sibling)
1010 {
1011 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1012 realloc_strings (ns);
1013 }
1014
1015 }
1016
1017 static void
1018 optimize_reduction (gfc_namespace *ns)
1019 {
1020 current_ns = ns;
1021 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1022 callback_reduction, NULL);
1023
1024 /* BLOCKs are handled in the expression walker below. */
1025 for (ns = ns->contained; ns; ns = ns->sibling)
1026 {
1027 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1028 optimize_reduction (ns);
1029 }
1030 }
1031
1032 /* Replace code like
1033 a = matmul(b,c) + d
1034 with
1035 a = matmul(b,c) ; a = a + d
1036 where the array function is not elemental and not allocatable
1037 and does not depend on the left-hand side.
1038 */
1039
1040 static bool
1041 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1042 {
1043 gfc_expr *e;
1044
1045 e = *rhs;
1046 if (e->expr_type == EXPR_OP)
1047 {
1048 switch (e->value.op.op)
1049 {
1050 /* Unary operators and exponentiation: Only look at a single
1051 operand. */
1052 case INTRINSIC_NOT:
1053 case INTRINSIC_UPLUS:
1054 case INTRINSIC_UMINUS:
1055 case INTRINSIC_PARENTHESES:
1056 case INTRINSIC_POWER:
1057 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
1058 return true;
1059 break;
1060
1061 case INTRINSIC_CONCAT:
1062 /* Do not do string concatenations. */
1063 break;
1064
1065 default:
1066 /* Binary operators. */
1067 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1068 return true;
1069
1070 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1071 return true;
1072
1073 break;
1074 }
1075 }
1076 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
1077 && ! (e->value.function.esym
1078 && (e->value.function.esym->attr.elemental
1079 || e->value.function.esym->attr.allocatable
1080 || e->value.function.esym->ts.type != c->expr1->ts.type
1081 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
1082 && ! (e->value.function.isym
1083 && (e->value.function.isym->elemental
1084 || e->ts.type != c->expr1->ts.type
1085 || e->ts.kind != c->expr1->ts.kind))
1086 && ! gfc_inline_intrinsic_function_p (e))
1087 {
1088
1089 gfc_code *n;
1090 gfc_expr *new_expr;
1091
1092 /* Insert a new assignment statement after the current one. */
1093 n = XCNEW (gfc_code);
1094 n->op = EXEC_ASSIGN;
1095 n->loc = c->loc;
1096 n->next = c->next;
1097 c->next = n;
1098
1099 n->expr1 = gfc_copy_expr (c->expr1);
1100 n->expr2 = c->expr2;
1101 new_expr = gfc_copy_expr (c->expr1);
1102 c->expr2 = e;
1103 *rhs = new_expr;
1104
1105 return true;
1106
1107 }
1108
1109 /* Nothing to optimize. */
1110 return false;
1111 }
1112
1113 /* Remove unneeded TRIMs at the end of expressions. */
1114
1115 static bool
1116 remove_trim (gfc_expr *rhs)
1117 {
1118 bool ret;
1119
1120 ret = false;
1121
1122 /* Check for a // b // trim(c). Looping is probably not
1123 necessary because the parser usually generates
1124 (// (// a b ) trim(c) ) , but better safe than sorry. */
1125
1126 while (rhs->expr_type == EXPR_OP
1127 && rhs->value.op.op == INTRINSIC_CONCAT)
1128 rhs = rhs->value.op.op2;
1129
1130 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1131 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1132 {
1133 strip_function_call (rhs);
1134 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1135 remove_trim (rhs);
1136 ret = true;
1137 }
1138
1139 return ret;
1140 }
1141
1142 /* Optimizations for an assignment. */
1143
1144 static void
1145 optimize_assignment (gfc_code * c)
1146 {
1147 gfc_expr *lhs, *rhs;
1148
1149 lhs = c->expr1;
1150 rhs = c->expr2;
1151
1152 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1153 {
1154 /* Optimize a = trim(b) to a = b. */
1155 remove_trim (rhs);
1156
1157 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1158 if (is_empty_string (rhs))
1159 rhs->value.character.length = 0;
1160 }
1161
1162 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1163 optimize_binop_array_assignment (c, &rhs, false);
1164 }
1165
1166
1167 /* Remove an unneeded function call, modifying the expression.
1168 This replaces the function call with the value of its
1169 first argument. The rest of the argument list is freed. */
1170
1171 static void
1172 strip_function_call (gfc_expr *e)
1173 {
1174 gfc_expr *e1;
1175 gfc_actual_arglist *a;
1176
1177 a = e->value.function.actual;
1178
1179 /* We should have at least one argument. */
1180 gcc_assert (a->expr != NULL);
1181
1182 e1 = a->expr;
1183
1184 /* Free the remaining arglist, if any. */
1185 if (a->next)
1186 gfc_free_actual_arglist (a->next);
1187
1188 /* Graft the argument expression onto the original function. */
1189 *e = *e1;
1190 free (e1);
1191
1192 }
1193
1194 /* Optimization of lexical comparison functions. */
1195
1196 static bool
1197 optimize_lexical_comparison (gfc_expr *e)
1198 {
1199 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1200 return false;
1201
1202 switch (e->value.function.isym->id)
1203 {
1204 case GFC_ISYM_LLE:
1205 return optimize_comparison (e, INTRINSIC_LE);
1206
1207 case GFC_ISYM_LGE:
1208 return optimize_comparison (e, INTRINSIC_GE);
1209
1210 case GFC_ISYM_LGT:
1211 return optimize_comparison (e, INTRINSIC_GT);
1212
1213 case GFC_ISYM_LLT:
1214 return optimize_comparison (e, INTRINSIC_LT);
1215
1216 default:
1217 break;
1218 }
1219 return false;
1220 }
1221
1222 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1223 do CHARACTER because of possible pessimization involving character
1224 lengths. */
1225
1226 static bool
1227 combine_array_constructor (gfc_expr *e)
1228 {
1229
1230 gfc_expr *op1, *op2;
1231 gfc_expr *scalar;
1232 gfc_expr *new_expr;
1233 gfc_constructor *c, *new_c;
1234 gfc_constructor_base oldbase, newbase;
1235 bool scalar_first;
1236
1237 /* Array constructors have rank one. */
1238 if (e->rank != 1)
1239 return false;
1240
1241 /* Don't try to combine association lists, this makes no sense
1242 and leads to an ICE. */
1243 if (in_assoc_list)
1244 return false;
1245
1246 op1 = e->value.op.op1;
1247 op2 = e->value.op.op2;
1248
1249 if (op1->expr_type == EXPR_ARRAY && op2->rank == 0)
1250 scalar_first = false;
1251 else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0)
1252 {
1253 scalar_first = true;
1254 op1 = e->value.op.op2;
1255 op2 = e->value.op.op1;
1256 }
1257 else
1258 return false;
1259
1260 if (op2->ts.type == BT_CHARACTER)
1261 return false;
1262
1263 scalar = create_var (gfc_copy_expr (op2), "constr");
1264
1265 oldbase = op1->value.constructor;
1266 newbase = NULL;
1267 e->expr_type = EXPR_ARRAY;
1268
1269 for (c = gfc_constructor_first (oldbase); c;
1270 c = gfc_constructor_next (c))
1271 {
1272 new_expr = gfc_get_expr ();
1273 new_expr->ts = e->ts;
1274 new_expr->expr_type = EXPR_OP;
1275 new_expr->rank = c->expr->rank;
1276 new_expr->where = c->where;
1277 new_expr->value.op.op = e->value.op.op;
1278
1279 if (scalar_first)
1280 {
1281 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1282 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1283 }
1284 else
1285 {
1286 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1287 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1288 }
1289
1290 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1291 new_c->iterator = c->iterator;
1292 c->iterator = NULL;
1293 }
1294
1295 gfc_free_expr (op1);
1296 gfc_free_expr (op2);
1297 gfc_free_expr (scalar);
1298
1299 e->value.constructor = newbase;
1300 return true;
1301 }
1302
1303 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1304 2**k into ishift(1,k) */
1305
1306 static bool
1307 optimize_power (gfc_expr *e)
1308 {
1309 gfc_expr *op1, *op2;
1310 gfc_expr *iand, *ishft;
1311
1312 if (e->ts.type != BT_INTEGER)
1313 return false;
1314
1315 op1 = e->value.op.op1;
1316
1317 if (op1 == NULL || op1->expr_type != EXPR_CONSTANT)
1318 return false;
1319
1320 if (mpz_cmp_si (op1->value.integer, -1L) == 0)
1321 {
1322 gfc_free_expr (op1);
1323
1324 op2 = e->value.op.op2;
1325
1326 if (op2 == NULL)
1327 return false;
1328
1329 iand = gfc_build_intrinsic_call (current_ns, GFC_ISYM_IAND,
1330 "_internal_iand", e->where, 2, op2,
1331 gfc_get_int_expr (e->ts.kind,
1332 &e->where, 1));
1333
1334 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1335 "_internal_ishft", e->where, 2, iand,
1336 gfc_get_int_expr (e->ts.kind,
1337 &e->where, 1));
1338
1339 e->value.op.op = INTRINSIC_MINUS;
1340 e->value.op.op1 = gfc_get_int_expr (e->ts.kind, &e->where, 1);
1341 e->value.op.op2 = ishft;
1342 return true;
1343 }
1344 else if (mpz_cmp_si (op1->value.integer, 2L) == 0)
1345 {
1346 gfc_free_expr (op1);
1347
1348 op2 = e->value.op.op2;
1349 if (op2 == NULL)
1350 return false;
1351
1352 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1353 "_internal_ishft", e->where, 2,
1354 gfc_get_int_expr (e->ts.kind,
1355 &e->where, 1),
1356 op2);
1357 *e = *ishft;
1358 return true;
1359 }
1360
1361 else if (mpz_cmp_si (op1->value.integer, 1L) == 0)
1362 {
1363 op2 = e->value.op.op2;
1364 if (op2 == NULL)
1365 return false;
1366
1367 gfc_free_expr (op1);
1368 gfc_free_expr (op2);
1369
1370 e->expr_type = EXPR_CONSTANT;
1371 e->value.op.op1 = NULL;
1372 e->value.op.op2 = NULL;
1373 mpz_init_set_si (e->value.integer, 1);
1374 /* Typespec and location are still OK. */
1375 return true;
1376 }
1377
1378 return false;
1379 }
1380
1381 /* Recursive optimization of operators. */
1382
1383 static bool
1384 optimize_op (gfc_expr *e)
1385 {
1386 bool changed;
1387
1388 gfc_intrinsic_op op = e->value.op.op;
1389
1390 changed = false;
1391
1392 /* Only use new-style comparisons. */
1393 switch(op)
1394 {
1395 case INTRINSIC_EQ_OS:
1396 op = INTRINSIC_EQ;
1397 break;
1398
1399 case INTRINSIC_GE_OS:
1400 op = INTRINSIC_GE;
1401 break;
1402
1403 case INTRINSIC_LE_OS:
1404 op = INTRINSIC_LE;
1405 break;
1406
1407 case INTRINSIC_NE_OS:
1408 op = INTRINSIC_NE;
1409 break;
1410
1411 case INTRINSIC_GT_OS:
1412 op = INTRINSIC_GT;
1413 break;
1414
1415 case INTRINSIC_LT_OS:
1416 op = INTRINSIC_LT;
1417 break;
1418
1419 default:
1420 break;
1421 }
1422
1423 switch (op)
1424 {
1425 case INTRINSIC_EQ:
1426 case INTRINSIC_GE:
1427 case INTRINSIC_LE:
1428 case INTRINSIC_NE:
1429 case INTRINSIC_GT:
1430 case INTRINSIC_LT:
1431 changed = optimize_comparison (e, op);
1432
1433 /* Fall through */
1434 /* Look at array constructors. */
1435 case INTRINSIC_PLUS:
1436 case INTRINSIC_MINUS:
1437 case INTRINSIC_TIMES:
1438 case INTRINSIC_DIVIDE:
1439 return combine_array_constructor (e) || changed;
1440
1441 case INTRINSIC_POWER:
1442 return optimize_power (e);
1443 break;
1444
1445 default:
1446 break;
1447 }
1448
1449 return false;
1450 }
1451
1452
1453 /* Return true if a constant string contains only blanks. */
1454
1455 static bool
1456 is_empty_string (gfc_expr *e)
1457 {
1458 int i;
1459
1460 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1461 return false;
1462
1463 for (i=0; i < e->value.character.length; i++)
1464 {
1465 if (e->value.character.string[i] != ' ')
1466 return false;
1467 }
1468
1469 return true;
1470 }
1471
1472
1473 /* Insert a call to the intrinsic len_trim. Use a different name for
1474 the symbol tree so we don't run into trouble when the user has
1475 renamed len_trim for some reason. */
1476
1477 static gfc_expr*
1478 get_len_trim_call (gfc_expr *str, int kind)
1479 {
1480 gfc_expr *fcn;
1481 gfc_actual_arglist *actual_arglist, *next;
1482
1483 fcn = gfc_get_expr ();
1484 fcn->expr_type = EXPR_FUNCTION;
1485 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1486 actual_arglist = gfc_get_actual_arglist ();
1487 actual_arglist->expr = str;
1488 next = gfc_get_actual_arglist ();
1489 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, kind);
1490 actual_arglist->next = next;
1491
1492 fcn->value.function.actual = actual_arglist;
1493 fcn->where = str->where;
1494 fcn->ts.type = BT_INTEGER;
1495 fcn->ts.kind = gfc_charlen_int_kind;
1496
1497 gfc_get_sym_tree ("__internal_len_trim", current_ns, &fcn->symtree, false);
1498 fcn->symtree->n.sym->ts = fcn->ts;
1499 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1500 fcn->symtree->n.sym->attr.function = 1;
1501 fcn->symtree->n.sym->attr.elemental = 1;
1502 fcn->symtree->n.sym->attr.referenced = 1;
1503 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
1504 gfc_commit_symbol (fcn->symtree->n.sym);
1505
1506 return fcn;
1507 }
1508
1509 /* Optimize expressions for equality. */
1510
1511 static bool
1512 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1513 {
1514 gfc_expr *op1, *op2;
1515 bool change;
1516 int eq;
1517 bool result;
1518 gfc_actual_arglist *firstarg, *secondarg;
1519
1520 if (e->expr_type == EXPR_OP)
1521 {
1522 firstarg = NULL;
1523 secondarg = NULL;
1524 op1 = e->value.op.op1;
1525 op2 = e->value.op.op2;
1526 }
1527 else if (e->expr_type == EXPR_FUNCTION)
1528 {
1529 /* One of the lexical comparison functions. */
1530 firstarg = e->value.function.actual;
1531 secondarg = firstarg->next;
1532 op1 = firstarg->expr;
1533 op2 = secondarg->expr;
1534 }
1535 else
1536 gcc_unreachable ();
1537
1538 /* Strip off unneeded TRIM calls from string comparisons. */
1539
1540 change = remove_trim (op1);
1541
1542 if (remove_trim (op2))
1543 change = true;
1544
1545 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1546 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
1547 handles them well). However, there are also cases that need a non-scalar
1548 argument. For example the any intrinsic. See PR 45380. */
1549 if (e->rank > 0)
1550 return change;
1551
1552 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
1553 len_trim(a) != 0 */
1554 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
1555 && (op == INTRINSIC_EQ || op == INTRINSIC_NE))
1556 {
1557 bool empty_op1, empty_op2;
1558 empty_op1 = is_empty_string (op1);
1559 empty_op2 = is_empty_string (op2);
1560
1561 if (empty_op1 || empty_op2)
1562 {
1563 gfc_expr *fcn;
1564 gfc_expr *zero;
1565 gfc_expr *str;
1566
1567 /* This can only happen when an error for comparing
1568 characters of different kinds has already been issued. */
1569 if (empty_op1 && empty_op2)
1570 return false;
1571
1572 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
1573 str = empty_op1 ? op2 : op1;
1574
1575 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
1576
1577
1578 if (empty_op1)
1579 gfc_free_expr (op1);
1580 else
1581 gfc_free_expr (op2);
1582
1583 op1 = fcn;
1584 op2 = zero;
1585 e->value.op.op1 = fcn;
1586 e->value.op.op2 = zero;
1587 }
1588 }
1589
1590
1591 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
1592
1593 if (flag_finite_math_only
1594 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
1595 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
1596 {
1597 eq = gfc_dep_compare_expr (op1, op2);
1598 if (eq <= -2)
1599 {
1600 /* Replace A // B < A // C with B < C, and A // B < C // B
1601 with A < C. */
1602 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
1603 && op1->expr_type == EXPR_OP
1604 && op1->value.op.op == INTRINSIC_CONCAT
1605 && op2->expr_type == EXPR_OP
1606 && op2->value.op.op == INTRINSIC_CONCAT)
1607 {
1608 gfc_expr *op1_left = op1->value.op.op1;
1609 gfc_expr *op2_left = op2->value.op.op1;
1610 gfc_expr *op1_right = op1->value.op.op2;
1611 gfc_expr *op2_right = op2->value.op.op2;
1612
1613 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
1614 {
1615 /* Watch out for 'A ' // x vs. 'A' // x. */
1616
1617 if (op1_left->expr_type == EXPR_CONSTANT
1618 && op2_left->expr_type == EXPR_CONSTANT
1619 && op1_left->value.character.length
1620 != op2_left->value.character.length)
1621 return change;
1622 else
1623 {
1624 free (op1_left);
1625 free (op2_left);
1626 if (firstarg)
1627 {
1628 firstarg->expr = op1_right;
1629 secondarg->expr = op2_right;
1630 }
1631 else
1632 {
1633 e->value.op.op1 = op1_right;
1634 e->value.op.op2 = op2_right;
1635 }
1636 optimize_comparison (e, op);
1637 return true;
1638 }
1639 }
1640 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
1641 {
1642 free (op1_right);
1643 free (op2_right);
1644 if (firstarg)
1645 {
1646 firstarg->expr = op1_left;
1647 secondarg->expr = op2_left;
1648 }
1649 else
1650 {
1651 e->value.op.op1 = op1_left;
1652 e->value.op.op2 = op2_left;
1653 }
1654
1655 optimize_comparison (e, op);
1656 return true;
1657 }
1658 }
1659 }
1660 else
1661 {
1662 /* eq can only be -1, 0 or 1 at this point. */
1663 switch (op)
1664 {
1665 case INTRINSIC_EQ:
1666 result = eq == 0;
1667 break;
1668
1669 case INTRINSIC_GE:
1670 result = eq >= 0;
1671 break;
1672
1673 case INTRINSIC_LE:
1674 result = eq <= 0;
1675 break;
1676
1677 case INTRINSIC_NE:
1678 result = eq != 0;
1679 break;
1680
1681 case INTRINSIC_GT:
1682 result = eq > 0;
1683 break;
1684
1685 case INTRINSIC_LT:
1686 result = eq < 0;
1687 break;
1688
1689 default:
1690 gfc_internal_error ("illegal OP in optimize_comparison");
1691 break;
1692 }
1693
1694 /* Replace the expression by a constant expression. The typespec
1695 and where remains the way it is. */
1696 free (op1);
1697 free (op2);
1698 e->expr_type = EXPR_CONSTANT;
1699 e->value.logical = result;
1700 return true;
1701 }
1702 }
1703
1704 return change;
1705 }
1706
1707 /* Optimize a trim function by replacing it with an equivalent substring
1708 involving a call to len_trim. This only works for expressions where
1709 variables are trimmed. Return true if anything was modified. */
1710
1711 static bool
1712 optimize_trim (gfc_expr *e)
1713 {
1714 gfc_expr *a;
1715 gfc_ref *ref;
1716 gfc_expr *fcn;
1717 gfc_ref **rr = NULL;
1718
1719 /* Don't do this optimization within an argument list, because
1720 otherwise aliasing issues may occur. */
1721
1722 if (count_arglist != 1)
1723 return false;
1724
1725 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
1726 || e->value.function.isym == NULL
1727 || e->value.function.isym->id != GFC_ISYM_TRIM)
1728 return false;
1729
1730 a = e->value.function.actual->expr;
1731
1732 if (a->expr_type != EXPR_VARIABLE)
1733 return false;
1734
1735 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
1736
1737 if (a->symtree->n.sym->attr.allocatable)
1738 return false;
1739
1740 /* Follow all references to find the correct place to put the newly
1741 created reference. FIXME: Also handle substring references and
1742 array references. Array references cause strange regressions at
1743 the moment. */
1744
1745 if (a->ref)
1746 {
1747 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
1748 {
1749 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
1750 return false;
1751 }
1752 }
1753
1754 strip_function_call (e);
1755
1756 if (e->ref == NULL)
1757 rr = &(e->ref);
1758
1759 /* Create the reference. */
1760
1761 ref = gfc_get_ref ();
1762 ref->type = REF_SUBSTRING;
1763
1764 /* Set the start of the reference. */
1765
1766 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1767
1768 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
1769
1770 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_default_integer_kind);
1771
1772 /* Set the end of the reference to the call to len_trim. */
1773
1774 ref->u.ss.end = fcn;
1775 gcc_assert (rr != NULL && *rr == NULL);
1776 *rr = ref;
1777 return true;
1778 }
1779
1780 /* Optimize minloc(b), where b is rank 1 array, into
1781 (/ minloc(b, dim=1) /), and similarly for maxloc,
1782 as the latter forms are expanded inline. */
1783
1784 static void
1785 optimize_minmaxloc (gfc_expr **e)
1786 {
1787 gfc_expr *fn = *e;
1788 gfc_actual_arglist *a;
1789 char *name, *p;
1790
1791 if (fn->rank != 1
1792 || fn->value.function.actual == NULL
1793 || fn->value.function.actual->expr == NULL
1794 || fn->value.function.actual->expr->rank != 1)
1795 return;
1796
1797 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
1798 (*e)->shape = fn->shape;
1799 fn->rank = 0;
1800 fn->shape = NULL;
1801 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
1802
1803 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
1804 strcpy (name, fn->value.function.name);
1805 p = strstr (name, "loc0");
1806 p[3] = '1';
1807 fn->value.function.name = gfc_get_string (name);
1808 if (fn->value.function.actual->next)
1809 {
1810 a = fn->value.function.actual->next;
1811 gcc_assert (a->expr == NULL);
1812 }
1813 else
1814 {
1815 a = gfc_get_actual_arglist ();
1816 fn->value.function.actual->next = a;
1817 }
1818 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
1819 &fn->where);
1820 mpz_set_ui (a->expr->value.integer, 1);
1821 }
1822
1823 /* Callback function for code checking that we do not pass a DO variable to an
1824 INTENT(OUT) or INTENT(INOUT) dummy variable. */
1825
1826 static int
1827 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1828 void *data ATTRIBUTE_UNUSED)
1829 {
1830 gfc_code *co;
1831 int i;
1832 gfc_formal_arglist *f;
1833 gfc_actual_arglist *a;
1834 gfc_code *cl;
1835
1836 co = *c;
1837
1838 /* If the doloop_list grew, we have to truncate it here. */
1839
1840 if ((unsigned) doloop_level < doloop_list.length())
1841 doloop_list.truncate (doloop_level);
1842
1843 switch (co->op)
1844 {
1845 case EXEC_DO:
1846
1847 if (co->ext.iterator && co->ext.iterator->var)
1848 doloop_list.safe_push (co);
1849 else
1850 doloop_list.safe_push ((gfc_code *) NULL);
1851 break;
1852
1853 case EXEC_CALL:
1854
1855 if (co->resolved_sym == NULL)
1856 break;
1857
1858 f = gfc_sym_get_dummy_args (co->resolved_sym);
1859
1860 /* Withot a formal arglist, there is only unknown INTENT,
1861 which we don't check for. */
1862 if (f == NULL)
1863 break;
1864
1865 a = co->ext.actual;
1866
1867 while (a && f)
1868 {
1869 FOR_EACH_VEC_ELT (doloop_list, i, cl)
1870 {
1871 gfc_symbol *do_sym;
1872
1873 if (cl == NULL)
1874 break;
1875
1876 do_sym = cl->ext.iterator->var->symtree->n.sym;
1877
1878 if (a->expr && a->expr->symtree
1879 && a->expr->symtree->n.sym == do_sym)
1880 {
1881 if (f->sym->attr.intent == INTENT_OUT)
1882 gfc_error_now_1 ("Variable '%s' at %L set to undefined "
1883 "value inside loop beginning at %L as "
1884 "INTENT(OUT) argument to subroutine '%s'",
1885 do_sym->name, &a->expr->where,
1886 &doloop_list[i]->loc,
1887 co->symtree->n.sym->name);
1888 else if (f->sym->attr.intent == INTENT_INOUT)
1889 gfc_error_now_1 ("Variable '%s' at %L not definable inside "
1890 "loop beginning at %L as INTENT(INOUT) "
1891 "argument to subroutine '%s'",
1892 do_sym->name, &a->expr->where,
1893 &doloop_list[i]->loc,
1894 co->symtree->n.sym->name);
1895 }
1896 }
1897 a = a->next;
1898 f = f->next;
1899 }
1900 break;
1901
1902 default:
1903 break;
1904 }
1905 return 0;
1906 }
1907
1908 /* Callback function for functions checking that we do not pass a DO variable
1909 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
1910
1911 static int
1912 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
1913 void *data ATTRIBUTE_UNUSED)
1914 {
1915 gfc_formal_arglist *f;
1916 gfc_actual_arglist *a;
1917 gfc_expr *expr;
1918 gfc_code *dl;
1919 int i;
1920
1921 expr = *e;
1922 if (expr->expr_type != EXPR_FUNCTION)
1923 return 0;
1924
1925 /* Intrinsic functions don't modify their arguments. */
1926
1927 if (expr->value.function.isym)
1928 return 0;
1929
1930 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
1931
1932 /* Without a formal arglist, there is only unknown INTENT,
1933 which we don't check for. */
1934 if (f == NULL)
1935 return 0;
1936
1937 a = expr->value.function.actual;
1938
1939 while (a && f)
1940 {
1941 FOR_EACH_VEC_ELT (doloop_list, i, dl)
1942 {
1943 gfc_symbol *do_sym;
1944
1945 if (dl == NULL)
1946 break;
1947
1948 do_sym = dl->ext.iterator->var->symtree->n.sym;
1949
1950 if (a->expr && a->expr->symtree
1951 && a->expr->symtree->n.sym == do_sym)
1952 {
1953 if (f->sym->attr.intent == INTENT_OUT)
1954 gfc_error_now_1 ("Variable '%s' at %L set to undefined value "
1955 "inside loop beginning at %L as INTENT(OUT) "
1956 "argument to function '%s'", do_sym->name,
1957 &a->expr->where, &doloop_list[i]->loc,
1958 expr->symtree->n.sym->name);
1959 else if (f->sym->attr.intent == INTENT_INOUT)
1960 gfc_error_now_1 ("Variable '%s' at %L not definable inside loop"
1961 " beginning at %L as INTENT(INOUT) argument to"
1962 " function '%s'", do_sym->name,
1963 &a->expr->where, &doloop_list[i]->loc,
1964 expr->symtree->n.sym->name);
1965 }
1966 }
1967 a = a->next;
1968 f = f->next;
1969 }
1970
1971 return 0;
1972 }
1973
1974 static void
1975 doloop_warn (gfc_namespace *ns)
1976 {
1977 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
1978 }
1979
1980 /* This selction deals with inlining calls to MATMUL. */
1981
1982 /* Auxiliary function to build and simplify an array inquiry function.
1983 dim is zero-based. */
1984
1985 static gfc_expr *
1986 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim)
1987 {
1988 gfc_expr *fcn;
1989 gfc_expr *dim_arg, *kind;
1990 const char *name;
1991 gfc_expr *ec;
1992
1993 switch (id)
1994 {
1995 case GFC_ISYM_LBOUND:
1996 name = "_gfortran_lbound";
1997 break;
1998
1999 case GFC_ISYM_UBOUND:
2000 name = "_gfortran_ubound";
2001 break;
2002
2003 case GFC_ISYM_SIZE:
2004 name = "_gfortran_size";
2005 break;
2006
2007 default:
2008 gcc_unreachable ();
2009 }
2010
2011 dim_arg = gfc_get_int_expr (gfc_default_integer_kind, &e->where, dim);
2012 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2013 gfc_index_integer_kind);
2014
2015 ec = gfc_copy_expr (e);
2016 fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3,
2017 ec, dim_arg, kind);
2018 gfc_simplify_expr (fcn, 0);
2019 return fcn;
2020 }
2021
2022 /* Builds a logical expression. */
2023
2024 static gfc_expr*
2025 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2026 {
2027 gfc_typespec ts;
2028 gfc_expr *res;
2029
2030 ts.type = BT_LOGICAL;
2031 ts.kind = gfc_default_logical_kind;
2032 res = gfc_get_expr ();
2033 res->where = e1->where;
2034 res->expr_type = EXPR_OP;
2035 res->value.op.op = op;
2036 res->value.op.op1 = e1;
2037 res->value.op.op2 = e2;
2038 res->ts = ts;
2039
2040 return res;
2041 }
2042
2043
2044 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
2045 compatible typespecs. */
2046
2047 static gfc_expr *
2048 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2049 {
2050 gfc_expr *res;
2051
2052 res = gfc_get_expr ();
2053 res->ts = e1->ts;
2054 res->where = e1->where;
2055 res->expr_type = EXPR_OP;
2056 res->value.op.op = op;
2057 res->value.op.op1 = e1;
2058 res->value.op.op2 = e2;
2059 gfc_simplify_expr (res, 0);
2060 return res;
2061 }
2062
2063 /* Generate the IF statement for a runtime check if we want to do inlining or
2064 not - putting in the code for both branches and putting it into the syntax
2065 tree is the caller's responsibility. For fixed array sizes, this should be
2066 removed by DCE. Only called for rank-two matrices A and B. */
2067
2068 static gfc_code *
2069 inline_limit_check (gfc_expr *a, gfc_expr *b, enum matrix_case m_case)
2070 {
2071 gfc_expr *inline_limit;
2072 gfc_code *if_1, *if_2, *else_2;
2073 gfc_expr *b2, *a2, *a1, *m1, *m2;
2074 gfc_typespec ts;
2075 gfc_expr *cond;
2076
2077 gcc_assert (m_case == A2B2);
2078
2079 /* Calculation is done in real to avoid integer overflow. */
2080
2081 inline_limit = gfc_get_constant_expr (BT_REAL, gfc_default_real_kind,
2082 &a->where);
2083 mpfr_set_si (inline_limit->value.real, flag_inline_matmul_limit,
2084 GFC_RND_MODE);
2085 mpfr_pow_ui (inline_limit->value.real, inline_limit->value.real, 3,
2086 GFC_RND_MODE);
2087
2088 a1 = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2089 a2 = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
2090 b2 = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2091
2092 gfc_clear_ts (&ts);
2093 ts.type = BT_REAL;
2094 ts.kind = gfc_default_real_kind;
2095 gfc_convert_type_warn (a1, &ts, 2, 0);
2096 gfc_convert_type_warn (a2, &ts, 2, 0);
2097 gfc_convert_type_warn (b2, &ts, 2, 0);
2098
2099 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
2100 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
2101
2102 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
2103 gfc_simplify_expr (cond, 0);
2104
2105 else_2 = XCNEW (gfc_code);
2106 else_2->op = EXEC_IF;
2107 else_2->loc = a->where;
2108
2109 if_2 = XCNEW (gfc_code);
2110 if_2->op = EXEC_IF;
2111 if_2->expr1 = cond;
2112 if_2->loc = a->where;
2113 if_2->block = else_2;
2114
2115 if_1 = XCNEW (gfc_code);
2116 if_1->op = EXEC_IF;
2117 if_1->block = if_2;
2118 if_1->loc = a->where;
2119
2120 return if_1;
2121 }
2122
2123
2124 /* Insert code to issue a runtime error if the expressions are not equal. */
2125
2126 static gfc_code *
2127 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
2128 {
2129 gfc_expr *cond;
2130 gfc_code *if_1, *if_2;
2131 gfc_code *c;
2132 gfc_actual_arglist *a1, *a2, *a3;
2133
2134 gcc_assert (e1->where.lb);
2135 /* Build the call to runtime_error. */
2136 c = XCNEW (gfc_code);
2137 c->op = EXEC_CALL;
2138 c->loc = e1->where;
2139
2140 /* Get a null-terminated message string. */
2141
2142 a1 = gfc_get_actual_arglist ();
2143 a1->expr = gfc_get_character_expr (gfc_default_character_kind, &e1->where,
2144 msg, strlen(msg)+1);
2145 c->ext.actual = a1;
2146
2147 /* Pass the value of the first expression. */
2148 a2 = gfc_get_actual_arglist ();
2149 a2->expr = gfc_copy_expr (e1);
2150 a1->next = a2;
2151
2152 /* Pass the value of the second expression. */
2153 a3 = gfc_get_actual_arglist ();
2154 a3->expr = gfc_copy_expr (e2);
2155 a2->next = a3;
2156
2157 gfc_check_fe_runtime_error (c->ext.actual);
2158 gfc_resolve_fe_runtime_error (c);
2159
2160 if_2 = XCNEW (gfc_code);
2161 if_2->op = EXEC_IF;
2162 if_2->loc = e1->where;
2163 if_2->next = c;
2164
2165 if_1 = XCNEW (gfc_code);
2166 if_1->op = EXEC_IF;
2167 if_1->block = if_2;
2168 if_1->loc = e1->where;
2169
2170 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
2171 gfc_simplify_expr (cond, 0);
2172 if_2->expr1 = cond;
2173
2174 return if_1;
2175 }
2176
2177 /* Handle matrix reallocation. Caller is responsible to insert into
2178 the code tree.
2179
2180 For the two-dimensional case, build
2181
2182 if (allocated(c)) then
2183 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
2184 deallocate(c)
2185 allocate (c(size(a,1), size(b,2)))
2186 end if
2187 else
2188 allocate (c(size(a,1),size(b,2)))
2189 end if
2190
2191 and for the other cases correspondingly.
2192 */
2193
2194 static gfc_code *
2195 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
2196 enum matrix_case m_case)
2197 {
2198
2199 gfc_expr *allocated, *alloc_expr;
2200 gfc_code *if_alloc_1, *if_alloc_2, *if_size_1, *if_size_2;
2201 gfc_code *else_alloc;
2202 gfc_code *deallocate, *allocate1, *allocate_else;
2203 gfc_array_ref *ar;
2204 gfc_expr *cond, *ne1, *ne2;
2205
2206 if (warn_realloc_lhs)
2207 gfc_warning (OPT_Wrealloc_lhs,
2208 "Code for reallocating the allocatable array at %L will "
2209 "be added", &c->where);
2210
2211 alloc_expr = gfc_copy_expr (c);
2212
2213 ar = gfc_find_array_ref (alloc_expr);
2214 gcc_assert (ar && ar->type == AR_FULL);
2215
2216 /* c comes in as a full ref. Change it into a copy and make it into an
2217 element ref so it has the right form for for ALLOCATE. In the same
2218 switch statement, also generate the size comparison for the secod IF
2219 statement. */
2220
2221 ar->type = AR_ELEMENT;
2222
2223 switch (m_case)
2224 {
2225 case A2B2:
2226 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2227 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2228 ne1 = build_logical_expr (INTRINSIC_NE,
2229 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2230 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
2231 ne2 = build_logical_expr (INTRINSIC_NE,
2232 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
2233 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2234 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
2235 break;
2236
2237 case A2B1:
2238 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2239 cond = build_logical_expr (INTRINSIC_NE,
2240 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2241 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
2242 break;
2243
2244 case A1B2:
2245 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
2246 cond = build_logical_expr (INTRINSIC_NE,
2247 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2248 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2249 break;
2250
2251 default:
2252 gcc_unreachable();
2253
2254 }
2255
2256 gfc_simplify_expr (cond, 0);
2257
2258 /* We need two identical allocate statements in two
2259 branches of the IF statement. */
2260
2261 allocate1 = XCNEW (gfc_code);
2262 allocate1->op = EXEC_ALLOCATE;
2263 allocate1->ext.alloc.list = gfc_get_alloc ();
2264 allocate1->loc = c->where;
2265 allocate1->ext.alloc.list->expr = gfc_copy_expr (alloc_expr);
2266
2267 allocate_else = XCNEW (gfc_code);
2268 allocate_else->op = EXEC_ALLOCATE;
2269 allocate_else->ext.alloc.list = gfc_get_alloc ();
2270 allocate_else->loc = c->where;
2271 allocate_else->ext.alloc.list->expr = alloc_expr;
2272
2273 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
2274 "_gfortran_allocated", c->where,
2275 1, gfc_copy_expr (c));
2276
2277 deallocate = XCNEW (gfc_code);
2278 deallocate->op = EXEC_DEALLOCATE;
2279 deallocate->ext.alloc.list = gfc_get_alloc ();
2280 deallocate->ext.alloc.list->expr = gfc_copy_expr (c);
2281 deallocate->next = allocate1;
2282 deallocate->loc = c->where;
2283
2284 if_size_2 = XCNEW (gfc_code);
2285 if_size_2->op = EXEC_IF;
2286 if_size_2->expr1 = cond;
2287 if_size_2->loc = c->where;
2288 if_size_2->next = deallocate;
2289
2290 if_size_1 = XCNEW (gfc_code);
2291 if_size_1->op = EXEC_IF;
2292 if_size_1->block = if_size_2;
2293 if_size_1->loc = c->where;
2294
2295 else_alloc = XCNEW (gfc_code);
2296 else_alloc->op = EXEC_IF;
2297 else_alloc->loc = c->where;
2298 else_alloc->next = allocate_else;
2299
2300 if_alloc_2 = XCNEW (gfc_code);
2301 if_alloc_2->op = EXEC_IF;
2302 if_alloc_2->expr1 = allocated;
2303 if_alloc_2->loc = c->where;
2304 if_alloc_2->next = if_size_1;
2305 if_alloc_2->block = else_alloc;
2306
2307 if_alloc_1 = XCNEW (gfc_code);
2308 if_alloc_1->op = EXEC_IF;
2309 if_alloc_1->block = if_alloc_2;
2310 if_alloc_1->loc = c->where;
2311
2312 return if_alloc_1;
2313 }
2314
2315 /* Callback function for has_function_or_op. */
2316
2317 static int
2318 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2319 void *data ATTRIBUTE_UNUSED)
2320 {
2321 if ((*e) == 0)
2322 return 0;
2323 else
2324 return (*e)->expr_type == EXPR_FUNCTION
2325 || (*e)->expr_type == EXPR_OP;
2326 }
2327
2328 /* Returns true if the expression contains a function. */
2329
2330 static bool
2331 has_function_or_op (gfc_expr **e)
2332 {
2333 if (e == NULL)
2334 return false;
2335 else
2336 return gfc_expr_walker (e, is_function_or_op, NULL);
2337 }
2338
2339 /* Freeze (assign to a temporary variable) a single expression. */
2340
2341 static void
2342 freeze_expr (gfc_expr **ep)
2343 {
2344 gfc_expr *ne;
2345 if (has_function_or_op (ep))
2346 {
2347 ne = create_var (*ep, "freeze");
2348 *ep = ne;
2349 }
2350 }
2351
2352 /* Go through an expression's references and assign them to temporary
2353 variables if they contain functions. This is usually done prior to
2354 front-end scalarization to avoid multiple invocations of functions. */
2355
2356 static void
2357 freeze_references (gfc_expr *e)
2358 {
2359 gfc_ref *r;
2360 gfc_array_ref *ar;
2361 int i;
2362
2363 for (r=e->ref; r; r=r->next)
2364 {
2365 if (r->type == REF_SUBSTRING)
2366 {
2367 if (r->u.ss.start != NULL)
2368 freeze_expr (&r->u.ss.start);
2369
2370 if (r->u.ss.end != NULL)
2371 freeze_expr (&r->u.ss.end);
2372 }
2373 else if (r->type == REF_ARRAY)
2374 {
2375 ar = &r->u.ar;
2376 switch (ar->type)
2377 {
2378 case AR_FULL:
2379 break;
2380
2381 case AR_SECTION:
2382 for (i=0; i<ar->dimen; i++)
2383 {
2384 if (ar->dimen_type[i] == DIMEN_RANGE)
2385 {
2386 freeze_expr (&ar->start[i]);
2387 freeze_expr (&ar->end[i]);
2388 freeze_expr (&ar->stride[i]);
2389 }
2390 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
2391 {
2392 freeze_expr (&ar->start[i]);
2393 }
2394 }
2395 break;
2396
2397 case AR_ELEMENT:
2398 for (i=0; i<ar->dimen; i++)
2399 freeze_expr (&ar->start[i]);
2400 break;
2401
2402 default:
2403 break;
2404 }
2405 }
2406 }
2407 }
2408
2409 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
2410
2411 static gfc_expr *
2412 convert_to_index_kind (gfc_expr *e)
2413 {
2414 gfc_expr *res;
2415
2416 gcc_assert (e != NULL);
2417
2418 res = gfc_copy_expr (e);
2419
2420 gcc_assert (e->ts.type == BT_INTEGER);
2421
2422 if (res->ts.kind != gfc_index_integer_kind)
2423 {
2424 gfc_typespec ts;
2425 gfc_clear_ts (&ts);
2426 ts.type = BT_INTEGER;
2427 ts.kind = gfc_index_integer_kind;
2428
2429 gfc_convert_type_warn (e, &ts, 2, 0);
2430 }
2431
2432 return res;
2433 }
2434
2435 /* Function to create a DO loop including creation of the
2436 iteration variable. gfc_expr are copied.*/
2437
2438 static gfc_code *
2439 create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where,
2440 gfc_namespace *ns, char *vname)
2441 {
2442
2443 char name[GFC_MAX_SYMBOL_LEN +1];
2444 gfc_symtree *symtree;
2445 gfc_symbol *symbol;
2446 gfc_expr *i;
2447 gfc_code *n, *n2;
2448
2449 /* Create an expression for the iteration variable. */
2450 if (vname)
2451 sprintf (name, "__var_%d_do_%s", var_num++, vname);
2452 else
2453 sprintf (name, "__var_%d_do", var_num++);
2454
2455
2456 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
2457 gcc_unreachable ();
2458
2459 /* Create the loop variable. */
2460
2461 symbol = symtree->n.sym;
2462 symbol->ts.type = BT_INTEGER;
2463 symbol->ts.kind = gfc_index_integer_kind;
2464 symbol->attr.flavor = FL_VARIABLE;
2465 symbol->attr.referenced = 1;
2466 symbol->attr.dimension = 0;
2467 symbol->attr.fe_temp = 1;
2468 gfc_commit_symbol (symbol);
2469
2470 i = gfc_get_expr ();
2471 i->expr_type = EXPR_VARIABLE;
2472 i->ts = symbol->ts;
2473 i->rank = 0;
2474 i->where = *where;
2475 i->symtree = symtree;
2476
2477 /* ... and the nested DO statements. */
2478 n = XCNEW (gfc_code);
2479 n->op = EXEC_DO;
2480 n->loc = *where;
2481 n->ext.iterator = gfc_get_iterator ();
2482 n->ext.iterator->var = i;
2483 n->ext.iterator->start = convert_to_index_kind (start);
2484 n->ext.iterator->end = convert_to_index_kind (end);
2485 if (step)
2486 n->ext.iterator->step = convert_to_index_kind (step);
2487 else
2488 n->ext.iterator->step = gfc_get_int_expr (gfc_index_integer_kind,
2489 where, 1);
2490
2491 n2 = XCNEW (gfc_code);
2492 n2->op = EXEC_DO;
2493 n2->loc = *where;
2494 n2->next = NULL;
2495 n->block = n2;
2496 return n;
2497 }
2498
2499 /* Get the upper bound of the DO loops for matmul along a dimension. This
2500 is one-based. */
2501
2502 static gfc_expr*
2503 get_size_m1 (gfc_expr *e, int dimen)
2504 {
2505 mpz_t size;
2506 gfc_expr *res;
2507
2508 if (gfc_array_dimen_size (e, dimen - 1, &size))
2509 {
2510 res = gfc_get_constant_expr (BT_INTEGER,
2511 gfc_index_integer_kind, &e->where);
2512 mpz_sub_ui (res->value.integer, size, 1);
2513 mpz_clear (size);
2514 }
2515 else
2516 {
2517 res = get_operand (INTRINSIC_MINUS,
2518 get_array_inq_function (GFC_ISYM_SIZE, e, dimen),
2519 gfc_get_int_expr (gfc_index_integer_kind,
2520 &e->where, 1));
2521 gfc_simplify_expr (res, 0);
2522 }
2523
2524 return res;
2525 }
2526
2527 /* Function to return a scalarized expression. It is assumed that indices are
2528 zero based to make generation of DO loops easier. A zero as index will
2529 access the first element along a dimension. Single element references will
2530 be skipped. A NULL as an expression will be replaced by a full reference.
2531 This assumes that the index loops have gfc_index_integer_kind, and that all
2532 references have been frozen. */
2533
2534 static gfc_expr*
2535 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
2536 {
2537 gfc_array_ref *ar;
2538 int i;
2539 int rank;
2540 gfc_expr *e;
2541 int i_index;
2542 bool was_fullref;
2543
2544 e = gfc_copy_expr(e_in);
2545
2546 rank = e->rank;
2547
2548 ar = gfc_find_array_ref (e);
2549
2550 /* We scalarize count_index variables, reducing the rank by count_index. */
2551
2552 e->rank = rank - count_index;
2553
2554 was_fullref = ar->type == AR_FULL;
2555
2556 if (e->rank == 0)
2557 ar->type = AR_ELEMENT;
2558 else
2559 ar->type = AR_SECTION;
2560
2561 /* Loop over the indices. For each index, create the expression
2562 index * stride + lbound(e, dim). */
2563
2564 i_index = 0;
2565 for (i=0; i < ar->dimen; i++)
2566 {
2567 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
2568 {
2569 if (index[i_index] != NULL)
2570 {
2571 gfc_expr *lbound, *nindex;
2572 gfc_expr *loopvar;
2573
2574 loopvar = gfc_copy_expr (index[i_index]);
2575
2576 if (ar->stride[i])
2577 {
2578 gfc_expr *tmp;
2579
2580 tmp = gfc_copy_expr(ar->stride[i]);
2581 if (tmp->ts.kind != gfc_index_integer_kind)
2582 {
2583 gfc_typespec ts;
2584 gfc_clear_ts (&ts);
2585 ts.type = BT_INTEGER;
2586 ts.kind = gfc_index_integer_kind;
2587 gfc_convert_type (tmp, &ts, 2);
2588 }
2589 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
2590 }
2591 else
2592 nindex = loopvar;
2593
2594 /* Calculate the lower bound of the expression. */
2595 if (ar->start[i])
2596 {
2597 lbound = gfc_copy_expr (ar->start[i]);
2598 if (lbound->ts.kind != gfc_index_integer_kind)
2599 {
2600 gfc_typespec ts;
2601 gfc_clear_ts (&ts);
2602 ts.type = BT_INTEGER;
2603 ts.kind = gfc_index_integer_kind;
2604 gfc_convert_type (lbound, &ts, 2);
2605
2606 }
2607 }
2608 else
2609 {
2610 gfc_expr *lbound_e;
2611 gfc_ref *ref;
2612
2613 lbound_e = gfc_copy_expr (e_in);
2614
2615 for (ref = lbound_e->ref; ref; ref = ref->next)
2616 if (ref->type == REF_ARRAY
2617 && (ref->u.ar.type == AR_FULL
2618 || ref->u.ar.type == AR_SECTION))
2619 break;
2620
2621 if (ref->next)
2622 {
2623 gfc_free_ref_list (ref->next);
2624 ref->next = NULL;
2625 }
2626
2627 if (!was_fullref)
2628 {
2629 /* Look at full individual sections, like a(:). The first index
2630 is the lbound of a full ref. */
2631 int j;
2632 gfc_array_ref *ar;
2633
2634 ar = &ref->u.ar;
2635 ar->type = AR_FULL;
2636 for (j = 0; j < ar->dimen; j++)
2637 {
2638 gfc_free_expr (ar->start[j]);
2639 ar->start[j] = NULL;
2640 gfc_free_expr (ar->end[j]);
2641 ar->end[j] = NULL;
2642 gfc_free_expr (ar->stride[j]);
2643 ar->stride[j] = NULL;
2644 }
2645
2646 /* We have to get rid of the shape, if there is one. Do
2647 so by freeing it and calling gfc_resolve to rebuild
2648 it, if necessary. */
2649
2650 if (lbound_e->shape)
2651 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
2652
2653 lbound_e->rank = ar->dimen;
2654 gfc_resolve_expr (lbound_e);
2655 }
2656 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
2657 i + 1);
2658 gfc_free_expr (lbound_e);
2659 }
2660
2661 ar->dimen_type[i] = DIMEN_ELEMENT;
2662
2663 gfc_free_expr (ar->start[i]);
2664 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
2665
2666 gfc_free_expr (ar->end[i]);
2667 ar->end[i] = NULL;
2668 gfc_free_expr (ar->stride[i]);
2669 ar->stride[i] = NULL;
2670 gfc_simplify_expr (ar->start[i], 0);
2671 }
2672 else if (was_fullref)
2673 {
2674 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
2675 }
2676 i_index ++;
2677 }
2678 }
2679
2680 return e;
2681 }
2682
2683
2684 /* Inline assignments of the form c = matmul(a,b).
2685 Handle only the cases currently where b and c are rank-two arrays.
2686
2687 This basically translates the code to
2688
2689 BLOCK
2690 integer i,j,k
2691 c = 0
2692 do j=0, size(b,2)-1
2693 do k=0, size(a, 2)-1
2694 do i=0, size(a, 1)-1
2695 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
2696 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
2697 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
2698 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
2699 end do
2700 end do
2701 end do
2702 END BLOCK
2703
2704 */
2705
2706 static int
2707 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
2708 void *data ATTRIBUTE_UNUSED)
2709 {
2710 gfc_code *co = *c;
2711 gfc_expr *expr1, *expr2;
2712 gfc_expr *matrix_a, *matrix_b;
2713 gfc_actual_arglist *a, *b;
2714 gfc_code *do_1, *do_2, *do_3, *assign_zero, *assign_matmul;
2715 gfc_expr *zero_e;
2716 gfc_expr *u1, *u2, *u3;
2717 gfc_expr *list[2];
2718 gfc_expr *ascalar, *bscalar, *cscalar;
2719 gfc_expr *mult;
2720 gfc_expr *var_1, *var_2, *var_3;
2721 gfc_expr *zero;
2722 gfc_namespace *ns;
2723 gfc_intrinsic_op op_times, op_plus;
2724 enum matrix_case m_case;
2725 int i;
2726 gfc_code *if_limit = NULL;
2727 gfc_code **next_code_point;
2728
2729 if (co->op != EXEC_ASSIGN)
2730 return 0;
2731
2732 expr1 = co->expr1;
2733 expr2 = co->expr2;
2734 if (expr2->expr_type != EXPR_FUNCTION
2735 || expr2->value.function.isym == NULL
2736 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
2737 return 0;
2738
2739 current_code = c;
2740 inserted_block = NULL;
2741 changed_statement = NULL;
2742
2743 a = expr2->value.function.actual;
2744 matrix_a = a->expr;
2745 b = a->next;
2746 matrix_b = b->expr;
2747
2748 /* Currently only handling direct variables. Transpose etc. will come
2749 later. */
2750
2751 if (matrix_a->expr_type != EXPR_VARIABLE
2752 || matrix_b->expr_type != EXPR_VARIABLE)
2753 return 0;
2754
2755 if (matrix_a->rank == 2)
2756 m_case = matrix_b->rank == 1 ? A2B1 : A2B2;
2757 else
2758 m_case = A1B2;
2759
2760 /* We do not handle data dependencies yet. */
2761 if (gfc_check_dependency (expr1, matrix_a, true)
2762 || gfc_check_dependency (expr1, matrix_b, true))
2763 return 0;
2764
2765 ns = insert_block ();
2766
2767 /* Assign the type of the zero expression for initializing the resulting
2768 array, and the expression (+ and * for real, integer and complex;
2769 .and. and .or for logical. */
2770
2771 switch(expr1->ts.type)
2772 {
2773 case BT_INTEGER:
2774 zero_e = gfc_get_int_expr (expr1->ts.kind, &expr1->where, 0);
2775 op_times = INTRINSIC_TIMES;
2776 op_plus = INTRINSIC_PLUS;
2777 break;
2778
2779 case BT_LOGICAL:
2780 op_times = INTRINSIC_AND;
2781 op_plus = INTRINSIC_OR;
2782 zero_e = gfc_get_logical_expr (expr1->ts.kind, &expr1->where,
2783 0);
2784 break;
2785 case BT_REAL:
2786 zero_e = gfc_get_constant_expr (BT_REAL, expr1->ts.kind,
2787 &expr1->where);
2788 mpfr_set_si (zero_e->value.real, 0, GFC_RND_MODE);
2789 op_times = INTRINSIC_TIMES;
2790 op_plus = INTRINSIC_PLUS;
2791 break;
2792
2793 case BT_COMPLEX:
2794 zero_e = gfc_get_constant_expr (BT_COMPLEX, expr1->ts.kind,
2795 &expr1->where);
2796 mpc_set_si_si (zero_e->value.complex, 0, 0, GFC_RND_MODE);
2797 op_times = INTRINSIC_TIMES;
2798 op_plus = INTRINSIC_PLUS;
2799
2800 break;
2801
2802 default:
2803 gcc_unreachable();
2804 }
2805
2806 current_code = &ns->code;
2807
2808 /* Freeze the references, keeping track of how many temporary variables were
2809 created. */
2810 n_vars = 0;
2811 freeze_references (matrix_a);
2812 freeze_references (matrix_b);
2813 freeze_references (expr1);
2814
2815 if (n_vars == 0)
2816 next_code_point = current_code;
2817 else
2818 {
2819 next_code_point = &ns->code;
2820 for (i=0; i<n_vars; i++)
2821 next_code_point = &(*next_code_point)->next;
2822 }
2823
2824 /* Take care of the inline flag. If the limit check evaluates to a
2825 constant, dead code elimination will eliminate the unneeded branch. */
2826
2827 if (m_case == A2B2 && flag_inline_matmul_limit > 0)
2828 {
2829 if_limit = inline_limit_check (matrix_a, matrix_b, m_case);
2830
2831 /* Insert the original statement into the else branch. */
2832 if_limit->block->block->next = co;
2833 co->next = NULL;
2834
2835 /* ... and the new ones go into the original one. */
2836 *next_code_point = if_limit;
2837 next_code_point = &if_limit->block->next;
2838 }
2839
2840 assign_zero = XCNEW (gfc_code);
2841 assign_zero->op = EXEC_ASSIGN;
2842 assign_zero->loc = co->loc;
2843 assign_zero->expr1 = gfc_copy_expr (expr1);
2844 assign_zero->expr2 = zero_e;
2845
2846 /* Handle the reallocation, if needed. */
2847 if (flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1))
2848 {
2849 gfc_code *lhs_alloc;
2850
2851 /* Only need to check a single dimension for the A2B2 case for
2852 bounds checking, the rest will be allocated. */
2853
2854 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS && m_case == A2B2)
2855 {
2856 gfc_code *test;
2857 gfc_expr *a2, *b1;
2858
2859 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
2860 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
2861 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
2862 "in MATMUL intrinsic: Is %ld, should be %ld");
2863 *next_code_point = test;
2864 next_code_point = &test->next;
2865 }
2866
2867
2868 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
2869
2870 *next_code_point = lhs_alloc;
2871 next_code_point = &lhs_alloc->next;
2872
2873 }
2874 else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2875 {
2876 gfc_code *test;
2877 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
2878
2879 if (m_case == A2B2 || m_case == A2B1)
2880 {
2881 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
2882 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
2883 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
2884 "in MATMUL intrinsic: Is %ld, should be %ld");
2885 *next_code_point = test;
2886 next_code_point = &test->next;
2887
2888 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
2889 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
2890
2891 if (m_case == A2B2)
2892 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
2893 "MATMUL intrinsic for dimension 1: "
2894 "is %ld, should be %ld");
2895 else if (m_case == A2B1)
2896 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
2897 "MATMUL intrinsic: "
2898 "is %ld, should be %ld");
2899
2900
2901 *next_code_point = test;
2902 next_code_point = &test->next;
2903 }
2904 else if (m_case == A1B2)
2905 {
2906 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
2907 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
2908 test = runtime_error_ne (b1, a1, "Dimension of array B incorrect "
2909 "in MATMUL intrinsic: Is %ld, should be %ld");
2910 *next_code_point = test;
2911 next_code_point = &test->next;
2912
2913 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
2914 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
2915
2916 test = runtime_error_ne (c1, b2, "Incorrect extent in return array in "
2917 "MATMUL intrinsic: "
2918 "is %ld, should be %ld");
2919
2920 *next_code_point = test;
2921 next_code_point = &test->next;
2922 }
2923
2924 if (m_case == A2B2)
2925 {
2926 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
2927 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
2928 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
2929 "MATMUL intrinsic for dimension 2: is %ld, should be %ld");
2930
2931 *next_code_point = test;
2932 next_code_point = &test->next;
2933 }
2934 }
2935
2936 *next_code_point = assign_zero;
2937
2938 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
2939
2940 assign_matmul = XCNEW (gfc_code);
2941 assign_matmul->op = EXEC_ASSIGN;
2942 assign_matmul->loc = co->loc;
2943
2944 /* Get the bounds for the loops, create them and create the scalarized
2945 expressions. */
2946
2947 switch (m_case)
2948 {
2949 case A2B2:
2950 inline_limit_check (matrix_a, matrix_b, m_case);
2951
2952 u1 = get_size_m1 (matrix_b, 2);
2953 u2 = get_size_m1 (matrix_a, 2);
2954 u3 = get_size_m1 (matrix_a, 1);
2955
2956 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
2957 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
2958 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
2959
2960 do_1->block->next = do_2;
2961 do_2->block->next = do_3;
2962 do_3->block->next = assign_matmul;
2963
2964 var_1 = do_1->ext.iterator->var;
2965 var_2 = do_2->ext.iterator->var;
2966 var_3 = do_3->ext.iterator->var;
2967
2968 list[0] = var_3;
2969 list[1] = var_1;
2970 cscalar = scalarized_expr (co->expr1, list, 2);
2971
2972 list[0] = var_3;
2973 list[1] = var_2;
2974 ascalar = scalarized_expr (matrix_a, list, 2);
2975
2976 list[0] = var_2;
2977 list[1] = var_1;
2978 bscalar = scalarized_expr (matrix_b, list, 2);
2979
2980 break;
2981
2982 case A2B1:
2983 u1 = get_size_m1 (matrix_b, 1);
2984 u2 = get_size_m1 (matrix_a, 1);
2985
2986 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
2987 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
2988
2989 do_1->block->next = do_2;
2990 do_2->block->next = assign_matmul;
2991
2992 var_1 = do_1->ext.iterator->var;
2993 var_2 = do_2->ext.iterator->var;
2994
2995 list[0] = var_2;
2996 cscalar = scalarized_expr (co->expr1, list, 1);
2997
2998 list[0] = var_2;
2999 list[1] = var_1;
3000 ascalar = scalarized_expr (matrix_a, list, 2);
3001
3002 list[0] = var_1;
3003 bscalar = scalarized_expr (matrix_b, list, 1);
3004
3005 break;
3006
3007 case A1B2:
3008 u1 = get_size_m1 (matrix_b, 2);
3009 u2 = get_size_m1 (matrix_a, 1);
3010
3011 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3012 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3013
3014 do_1->block->next = do_2;
3015 do_2->block->next = assign_matmul;
3016
3017 var_1 = do_1->ext.iterator->var;
3018 var_2 = do_2->ext.iterator->var;
3019
3020 list[0] = var_1;
3021 cscalar = scalarized_expr (co->expr1, list, 1);
3022
3023 list[0] = var_2;
3024 ascalar = scalarized_expr (matrix_a, list, 1);
3025
3026 list[0] = var_2;
3027 list[1] = var_1;
3028 bscalar = scalarized_expr (matrix_b, list, 2);
3029
3030 break;
3031
3032 default:
3033 gcc_unreachable();
3034 }
3035
3036 /* First loop comes after the zero assignment. */
3037 assign_zero->next = do_1;
3038
3039 /* Build the assignment expression in the loop. */
3040 assign_matmul->expr1 = gfc_copy_expr (cscalar);
3041
3042 mult = get_operand (op_times, ascalar, bscalar);
3043 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
3044
3045 /* If we don't want to keep the original statement around in
3046 the else branch, we can free it. */
3047
3048 if (if_limit == NULL)
3049 gfc_free_statements(co);
3050 else
3051 co->next = NULL;
3052
3053 gfc_free_expr (zero);
3054 *walk_subtrees = 0;
3055 return 0;
3056 }
3057
3058 #define WALK_SUBEXPR(NODE) \
3059 do \
3060 { \
3061 result = gfc_expr_walker (&(NODE), exprfn, data); \
3062 if (result) \
3063 return result; \
3064 } \
3065 while (0)
3066 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
3067
3068 /* Walk expression *E, calling EXPRFN on each expression in it. */
3069
3070 int
3071 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
3072 {
3073 while (*e)
3074 {
3075 int walk_subtrees = 1;
3076 gfc_actual_arglist *a;
3077 gfc_ref *r;
3078 gfc_constructor *c;
3079
3080 int result = exprfn (e, &walk_subtrees, data);
3081 if (result)
3082 return result;
3083 if (walk_subtrees)
3084 switch ((*e)->expr_type)
3085 {
3086 case EXPR_OP:
3087 WALK_SUBEXPR ((*e)->value.op.op1);
3088 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
3089 break;
3090 case EXPR_FUNCTION:
3091 for (a = (*e)->value.function.actual; a; a = a->next)
3092 WALK_SUBEXPR (a->expr);
3093 break;
3094 case EXPR_COMPCALL:
3095 case EXPR_PPC:
3096 WALK_SUBEXPR ((*e)->value.compcall.base_object);
3097 for (a = (*e)->value.compcall.actual; a; a = a->next)
3098 WALK_SUBEXPR (a->expr);
3099 break;
3100
3101 case EXPR_STRUCTURE:
3102 case EXPR_ARRAY:
3103 for (c = gfc_constructor_first ((*e)->value.constructor); c;
3104 c = gfc_constructor_next (c))
3105 {
3106 if (c->iterator == NULL)
3107 WALK_SUBEXPR (c->expr);
3108 else
3109 {
3110 iterator_level ++;
3111 WALK_SUBEXPR (c->expr);
3112 iterator_level --;
3113 WALK_SUBEXPR (c->iterator->var);
3114 WALK_SUBEXPR (c->iterator->start);
3115 WALK_SUBEXPR (c->iterator->end);
3116 WALK_SUBEXPR (c->iterator->step);
3117 }
3118 }
3119
3120 if ((*e)->expr_type != EXPR_ARRAY)
3121 break;
3122
3123 /* Fall through to the variable case in order to walk the
3124 reference. */
3125
3126 case EXPR_SUBSTRING:
3127 case EXPR_VARIABLE:
3128 for (r = (*e)->ref; r; r = r->next)
3129 {
3130 gfc_array_ref *ar;
3131 int i;
3132
3133 switch (r->type)
3134 {
3135 case REF_ARRAY:
3136 ar = &r->u.ar;
3137 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
3138 {
3139 for (i=0; i< ar->dimen; i++)
3140 {
3141 WALK_SUBEXPR (ar->start[i]);
3142 WALK_SUBEXPR (ar->end[i]);
3143 WALK_SUBEXPR (ar->stride[i]);
3144 }
3145 }
3146
3147 break;
3148
3149 case REF_SUBSTRING:
3150 WALK_SUBEXPR (r->u.ss.start);
3151 WALK_SUBEXPR (r->u.ss.end);
3152 break;
3153
3154 case REF_COMPONENT:
3155 break;
3156 }
3157 }
3158
3159 default:
3160 break;
3161 }
3162 return 0;
3163 }
3164 return 0;
3165 }
3166
3167 #define WALK_SUBCODE(NODE) \
3168 do \
3169 { \
3170 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
3171 if (result) \
3172 return result; \
3173 } \
3174 while (0)
3175
3176 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
3177 on each expression in it. If any of the hooks returns non-zero, that
3178 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
3179 no subcodes or subexpressions are traversed. */
3180
3181 int
3182 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
3183 void *data)
3184 {
3185 for (; *c; c = &(*c)->next)
3186 {
3187 int walk_subtrees = 1;
3188 int result = codefn (c, &walk_subtrees, data);
3189 if (result)
3190 return result;
3191
3192 if (walk_subtrees)
3193 {
3194 gfc_code *b;
3195 gfc_actual_arglist *a;
3196 gfc_code *co;
3197 gfc_association_list *alist;
3198 bool saved_in_omp_workshare;
3199
3200 /* There might be statement insertions before the current code,
3201 which must not affect the expression walker. */
3202
3203 co = *c;
3204 saved_in_omp_workshare = in_omp_workshare;
3205
3206 switch (co->op)
3207 {
3208
3209 case EXEC_BLOCK:
3210 WALK_SUBCODE (co->ext.block.ns->code);
3211 if (co->ext.block.assoc)
3212 {
3213 bool saved_in_assoc_list = in_assoc_list;
3214
3215 in_assoc_list = true;
3216 for (alist = co->ext.block.assoc; alist; alist = alist->next)
3217 WALK_SUBEXPR (alist->target);
3218
3219 in_assoc_list = saved_in_assoc_list;
3220 }
3221
3222 break;
3223
3224 case EXEC_DO:
3225 doloop_level ++;
3226 WALK_SUBEXPR (co->ext.iterator->var);
3227 WALK_SUBEXPR (co->ext.iterator->start);
3228 WALK_SUBEXPR (co->ext.iterator->end);
3229 WALK_SUBEXPR (co->ext.iterator->step);
3230 break;
3231
3232 case EXEC_CALL:
3233 case EXEC_ASSIGN_CALL:
3234 for (a = co->ext.actual; a; a = a->next)
3235 WALK_SUBEXPR (a->expr);
3236 break;
3237
3238 case EXEC_CALL_PPC:
3239 WALK_SUBEXPR (co->expr1);
3240 for (a = co->ext.actual; a; a = a->next)
3241 WALK_SUBEXPR (a->expr);
3242 break;
3243
3244 case EXEC_SELECT:
3245 WALK_SUBEXPR (co->expr1);
3246 for (b = co->block; b; b = b->block)
3247 {
3248 gfc_case *cp;
3249 for (cp = b->ext.block.case_list; cp; cp = cp->next)
3250 {
3251 WALK_SUBEXPR (cp->low);
3252 WALK_SUBEXPR (cp->high);
3253 }
3254 WALK_SUBCODE (b->next);
3255 }
3256 continue;
3257
3258 case EXEC_ALLOCATE:
3259 case EXEC_DEALLOCATE:
3260 {
3261 gfc_alloc *a;
3262 for (a = co->ext.alloc.list; a; a = a->next)
3263 WALK_SUBEXPR (a->expr);
3264 break;
3265 }
3266
3267 case EXEC_FORALL:
3268 case EXEC_DO_CONCURRENT:
3269 {
3270 gfc_forall_iterator *fa;
3271 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
3272 {
3273 WALK_SUBEXPR (fa->var);
3274 WALK_SUBEXPR (fa->start);
3275 WALK_SUBEXPR (fa->end);
3276 WALK_SUBEXPR (fa->stride);
3277 }
3278 if (co->op == EXEC_FORALL)
3279 forall_level ++;
3280 break;
3281 }
3282
3283 case EXEC_OPEN:
3284 WALK_SUBEXPR (co->ext.open->unit);
3285 WALK_SUBEXPR (co->ext.open->file);
3286 WALK_SUBEXPR (co->ext.open->status);
3287 WALK_SUBEXPR (co->ext.open->access);
3288 WALK_SUBEXPR (co->ext.open->form);
3289 WALK_SUBEXPR (co->ext.open->recl);
3290 WALK_SUBEXPR (co->ext.open->blank);
3291 WALK_SUBEXPR (co->ext.open->position);
3292 WALK_SUBEXPR (co->ext.open->action);
3293 WALK_SUBEXPR (co->ext.open->delim);
3294 WALK_SUBEXPR (co->ext.open->pad);
3295 WALK_SUBEXPR (co->ext.open->iostat);
3296 WALK_SUBEXPR (co->ext.open->iomsg);
3297 WALK_SUBEXPR (co->ext.open->convert);
3298 WALK_SUBEXPR (co->ext.open->decimal);
3299 WALK_SUBEXPR (co->ext.open->encoding);
3300 WALK_SUBEXPR (co->ext.open->round);
3301 WALK_SUBEXPR (co->ext.open->sign);
3302 WALK_SUBEXPR (co->ext.open->asynchronous);
3303 WALK_SUBEXPR (co->ext.open->id);
3304 WALK_SUBEXPR (co->ext.open->newunit);
3305 break;
3306
3307 case EXEC_CLOSE:
3308 WALK_SUBEXPR (co->ext.close->unit);
3309 WALK_SUBEXPR (co->ext.close->status);
3310 WALK_SUBEXPR (co->ext.close->iostat);
3311 WALK_SUBEXPR (co->ext.close->iomsg);
3312 break;
3313
3314 case EXEC_BACKSPACE:
3315 case EXEC_ENDFILE:
3316 case EXEC_REWIND:
3317 case EXEC_FLUSH:
3318 WALK_SUBEXPR (co->ext.filepos->unit);
3319 WALK_SUBEXPR (co->ext.filepos->iostat);
3320 WALK_SUBEXPR (co->ext.filepos->iomsg);
3321 break;
3322
3323 case EXEC_INQUIRE:
3324 WALK_SUBEXPR (co->ext.inquire->unit);
3325 WALK_SUBEXPR (co->ext.inquire->file);
3326 WALK_SUBEXPR (co->ext.inquire->iomsg);
3327 WALK_SUBEXPR (co->ext.inquire->iostat);
3328 WALK_SUBEXPR (co->ext.inquire->exist);
3329 WALK_SUBEXPR (co->ext.inquire->opened);
3330 WALK_SUBEXPR (co->ext.inquire->number);
3331 WALK_SUBEXPR (co->ext.inquire->named);
3332 WALK_SUBEXPR (co->ext.inquire->name);
3333 WALK_SUBEXPR (co->ext.inquire->access);
3334 WALK_SUBEXPR (co->ext.inquire->sequential);
3335 WALK_SUBEXPR (co->ext.inquire->direct);
3336 WALK_SUBEXPR (co->ext.inquire->form);
3337 WALK_SUBEXPR (co->ext.inquire->formatted);
3338 WALK_SUBEXPR (co->ext.inquire->unformatted);
3339 WALK_SUBEXPR (co->ext.inquire->recl);
3340 WALK_SUBEXPR (co->ext.inquire->nextrec);
3341 WALK_SUBEXPR (co->ext.inquire->blank);
3342 WALK_SUBEXPR (co->ext.inquire->position);
3343 WALK_SUBEXPR (co->ext.inquire->action);
3344 WALK_SUBEXPR (co->ext.inquire->read);
3345 WALK_SUBEXPR (co->ext.inquire->write);
3346 WALK_SUBEXPR (co->ext.inquire->readwrite);
3347 WALK_SUBEXPR (co->ext.inquire->delim);
3348 WALK_SUBEXPR (co->ext.inquire->encoding);
3349 WALK_SUBEXPR (co->ext.inquire->pad);
3350 WALK_SUBEXPR (co->ext.inquire->iolength);
3351 WALK_SUBEXPR (co->ext.inquire->convert);
3352 WALK_SUBEXPR (co->ext.inquire->strm_pos);
3353 WALK_SUBEXPR (co->ext.inquire->asynchronous);
3354 WALK_SUBEXPR (co->ext.inquire->decimal);
3355 WALK_SUBEXPR (co->ext.inquire->pending);
3356 WALK_SUBEXPR (co->ext.inquire->id);
3357 WALK_SUBEXPR (co->ext.inquire->sign);
3358 WALK_SUBEXPR (co->ext.inquire->size);
3359 WALK_SUBEXPR (co->ext.inquire->round);
3360 break;
3361
3362 case EXEC_WAIT:
3363 WALK_SUBEXPR (co->ext.wait->unit);
3364 WALK_SUBEXPR (co->ext.wait->iostat);
3365 WALK_SUBEXPR (co->ext.wait->iomsg);
3366 WALK_SUBEXPR (co->ext.wait->id);
3367 break;
3368
3369 case EXEC_READ:
3370 case EXEC_WRITE:
3371 WALK_SUBEXPR (co->ext.dt->io_unit);
3372 WALK_SUBEXPR (co->ext.dt->format_expr);
3373 WALK_SUBEXPR (co->ext.dt->rec);
3374 WALK_SUBEXPR (co->ext.dt->advance);
3375 WALK_SUBEXPR (co->ext.dt->iostat);
3376 WALK_SUBEXPR (co->ext.dt->size);
3377 WALK_SUBEXPR (co->ext.dt->iomsg);
3378 WALK_SUBEXPR (co->ext.dt->id);
3379 WALK_SUBEXPR (co->ext.dt->pos);
3380 WALK_SUBEXPR (co->ext.dt->asynchronous);
3381 WALK_SUBEXPR (co->ext.dt->blank);
3382 WALK_SUBEXPR (co->ext.dt->decimal);
3383 WALK_SUBEXPR (co->ext.dt->delim);
3384 WALK_SUBEXPR (co->ext.dt->pad);
3385 WALK_SUBEXPR (co->ext.dt->round);
3386 WALK_SUBEXPR (co->ext.dt->sign);
3387 WALK_SUBEXPR (co->ext.dt->extra_comma);
3388 break;
3389
3390 case EXEC_OMP_PARALLEL:
3391 case EXEC_OMP_PARALLEL_DO:
3392 case EXEC_OMP_PARALLEL_DO_SIMD:
3393 case EXEC_OMP_PARALLEL_SECTIONS:
3394
3395 in_omp_workshare = false;
3396
3397 /* This goto serves as a shortcut to avoid code
3398 duplication or a larger if or switch statement. */
3399 goto check_omp_clauses;
3400
3401 case EXEC_OMP_WORKSHARE:
3402 case EXEC_OMP_PARALLEL_WORKSHARE:
3403
3404 in_omp_workshare = true;
3405
3406 /* Fall through */
3407
3408 case EXEC_OMP_DISTRIBUTE:
3409 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
3410 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
3411 case EXEC_OMP_DISTRIBUTE_SIMD:
3412 case EXEC_OMP_DO:
3413 case EXEC_OMP_DO_SIMD:
3414 case EXEC_OMP_SECTIONS:
3415 case EXEC_OMP_SINGLE:
3416 case EXEC_OMP_END_SINGLE:
3417 case EXEC_OMP_SIMD:
3418 case EXEC_OMP_TARGET:
3419 case EXEC_OMP_TARGET_DATA:
3420 case EXEC_OMP_TARGET_TEAMS:
3421 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
3422 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
3423 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
3424 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
3425 case EXEC_OMP_TARGET_UPDATE:
3426 case EXEC_OMP_TASK:
3427 case EXEC_OMP_TEAMS:
3428 case EXEC_OMP_TEAMS_DISTRIBUTE:
3429 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
3430 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
3431 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
3432
3433 /* Come to this label only from the
3434 EXEC_OMP_PARALLEL_* cases above. */
3435
3436 check_omp_clauses:
3437
3438 if (co->ext.omp_clauses)
3439 {
3440 gfc_omp_namelist *n;
3441 static int list_types[]
3442 = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
3443 OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
3444 size_t idx;
3445 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
3446 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
3447 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
3448 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
3449 WALK_SUBEXPR (co->ext.omp_clauses->safelen_expr);
3450 WALK_SUBEXPR (co->ext.omp_clauses->simdlen_expr);
3451 WALK_SUBEXPR (co->ext.omp_clauses->num_teams);
3452 WALK_SUBEXPR (co->ext.omp_clauses->device);
3453 WALK_SUBEXPR (co->ext.omp_clauses->thread_limit);
3454 WALK_SUBEXPR (co->ext.omp_clauses->dist_chunk_size);
3455 for (idx = 0;
3456 idx < sizeof (list_types) / sizeof (list_types[0]);
3457 idx++)
3458 for (n = co->ext.omp_clauses->lists[list_types[idx]];
3459 n; n = n->next)
3460 WALK_SUBEXPR (n->expr);
3461 }
3462 break;
3463 default:
3464 break;
3465 }
3466
3467 WALK_SUBEXPR (co->expr1);
3468 WALK_SUBEXPR (co->expr2);
3469 WALK_SUBEXPR (co->expr3);
3470 WALK_SUBEXPR (co->expr4);
3471 for (b = co->block; b; b = b->block)
3472 {
3473 WALK_SUBEXPR (b->expr1);
3474 WALK_SUBEXPR (b->expr2);
3475 WALK_SUBCODE (b->next);
3476 }
3477
3478 if (co->op == EXEC_FORALL)
3479 forall_level --;
3480
3481 if (co->op == EXEC_DO)
3482 doloop_level --;
3483
3484 in_omp_workshare = saved_in_omp_workshare;
3485 }
3486 }
3487 return 0;
3488 }