2015-12-18 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / fortran / frontend-passes.c
blob22b4ce723751b19d8bcc4a5603c63d09eb9f6508
1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2015 Free Software Foundation, Inc.
3 Contributed by Thomas König.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "options.h"
25 #include "gfortran.h"
26 #include "dependency.h"
27 #include "constructor.h"
28 #include "intrinsic.h"
30 /* Forward declarations. */
32 static void strip_function_call (gfc_expr *);
33 static void optimize_namespace (gfc_namespace *);
34 static void optimize_assignment (gfc_code *);
35 static bool optimize_op (gfc_expr *);
36 static bool optimize_comparison (gfc_expr *, gfc_intrinsic_op);
37 static bool optimize_trim (gfc_expr *);
38 static bool optimize_lexical_comparison (gfc_expr *);
39 static void optimize_minmaxloc (gfc_expr **);
40 static bool is_empty_string (gfc_expr *e);
41 static void doloop_warn (gfc_namespace *);
42 static void optimize_reduction (gfc_namespace *);
43 static int callback_reduction (gfc_expr **, int *, void *);
44 static void realloc_strings (gfc_namespace *);
45 static gfc_expr *create_var (gfc_expr *, const char *vname=NULL);
46 static int inline_matmul_assign (gfc_code **, int *, void *);
47 static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *,
48 locus *, gfc_namespace *,
49 char *vname=NULL);
51 /* How deep we are inside an argument list. */
53 static int count_arglist;
55 /* Vector of gfc_expr ** we operate on. */
57 static vec<gfc_expr **> expr_array;
59 /* Pointer to the gfc_code we currently work on - to be able to insert
60 a block before the statement. */
62 static gfc_code **current_code;
64 /* Pointer to the block to be inserted, and the statement we are
65 changing within the block. */
67 static gfc_code *inserted_block, **changed_statement;
69 /* The namespace we are currently dealing with. */
71 static gfc_namespace *current_ns;
73 /* If we are within any forall loop. */
75 static int forall_level;
77 /* Keep track of whether we are within an OMP workshare. */
79 static bool in_omp_workshare;
81 /* Keep track of iterators for array constructors. */
83 static int iterator_level;
85 /* Keep track of DO loop levels. */
87 static vec<gfc_code *> doloop_list;
89 static int doloop_level;
91 /* Vector of gfc_expr * to keep track of DO loops. */
93 struct my_struct *evec;
95 /* Keep track of association lists. */
97 static bool in_assoc_list;
99 /* Counter for temporary variables. */
101 static int var_num = 1;
103 /* What sort of matrix we are dealing with when inlining MATMUL. */
105 enum matrix_case { none=0, A2B2, A2B1, A1B2 };
107 /* Keep track of the number of expressions we have inserted so far
108 using create_var. */
110 int n_vars;
112 /* Entry point - run all passes for a namespace. */
114 void
115 gfc_run_passes (gfc_namespace *ns)
118 /* Warn about dubious DO loops where the index might
119 change. */
121 doloop_level = 0;
122 doloop_warn (ns);
123 doloop_list.release ();
125 if (flag_frontend_optimize)
127 optimize_namespace (ns);
128 optimize_reduction (ns);
129 if (flag_dump_fortran_optimized)
130 gfc_dump_parse_tree (ns, stdout);
132 expr_array.release ();
135 if (flag_realloc_lhs)
136 realloc_strings (ns);
139 /* Callback for each gfc_code node invoked from check_realloc_strings.
140 For an allocatable LHS string which also appears as a variable on
141 the RHS, replace
143 a = a(x:y)
145 with
147 tmp = a(x:y)
148 a = tmp
151 static int
152 realloc_string_callback (gfc_code **c, int *walk_subtrees,
153 void *data ATTRIBUTE_UNUSED)
155 gfc_expr *expr1, *expr2;
156 gfc_code *co = *c;
157 gfc_expr *n;
159 *walk_subtrees = 0;
160 if (co->op != EXEC_ASSIGN)
161 return 0;
163 expr1 = co->expr1;
164 if (expr1->ts.type != BT_CHARACTER || expr1->rank != 0
165 || !expr1->symtree->n.sym->attr.allocatable)
166 return 0;
168 expr2 = gfc_discard_nops (co->expr2);
169 if (expr2->expr_type != EXPR_VARIABLE)
170 return 0;
172 if (!gfc_check_dependency (expr1, expr2, true))
173 return 0;
175 current_code = c;
176 n = create_var (expr2, "trim");
177 co->expr2 = n;
178 return 0;
181 /* Callback for each gfc_code node invoked through gfc_code_walker
182 from optimize_namespace. */
184 static int
185 optimize_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
186 void *data ATTRIBUTE_UNUSED)
189 gfc_exec_op op;
191 op = (*c)->op;
193 if (op == EXEC_CALL || op == EXEC_COMPCALL || op == EXEC_ASSIGN_CALL
194 || op == EXEC_CALL_PPC)
195 count_arglist = 1;
196 else
197 count_arglist = 0;
199 current_code = c;
200 inserted_block = NULL;
201 changed_statement = NULL;
203 if (op == EXEC_ASSIGN)
204 optimize_assignment (*c);
205 return 0;
208 /* Callback for each gfc_expr node invoked through gfc_code_walker
209 from optimize_namespace. */
211 static int
212 optimize_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
213 void *data ATTRIBUTE_UNUSED)
215 bool function_expr;
217 if ((*e)->expr_type == EXPR_FUNCTION)
219 count_arglist ++;
220 function_expr = true;
222 else
223 function_expr = false;
225 if (optimize_trim (*e))
226 gfc_simplify_expr (*e, 0);
228 if (optimize_lexical_comparison (*e))
229 gfc_simplify_expr (*e, 0);
231 if ((*e)->expr_type == EXPR_OP && optimize_op (*e))
232 gfc_simplify_expr (*e, 0);
234 if ((*e)->expr_type == EXPR_FUNCTION && (*e)->value.function.isym)
235 switch ((*e)->value.function.isym->id)
237 case GFC_ISYM_MINLOC:
238 case GFC_ISYM_MAXLOC:
239 optimize_minmaxloc (e);
240 break;
241 default:
242 break;
245 if (function_expr)
246 count_arglist --;
248 return 0;
251 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
252 function is a scalar, just copy it; otherwise returns the new element, the
253 old one can be freed. */
255 static gfc_expr *
256 copy_walk_reduction_arg (gfc_constructor *c, gfc_expr *fn)
258 gfc_expr *fcn, *e = c->expr;
260 fcn = gfc_copy_expr (e);
261 if (c->iterator)
263 gfc_constructor_base newbase;
264 gfc_expr *new_expr;
265 gfc_constructor *new_c;
267 newbase = NULL;
268 new_expr = gfc_get_expr ();
269 new_expr->expr_type = EXPR_ARRAY;
270 new_expr->ts = e->ts;
271 new_expr->where = e->where;
272 new_expr->rank = 1;
273 new_c = gfc_constructor_append_expr (&newbase, fcn, &(e->where));
274 new_c->iterator = c->iterator;
275 new_expr->value.constructor = newbase;
276 c->iterator = NULL;
278 fcn = new_expr;
281 if (fcn->rank != 0)
283 gfc_isym_id id = fn->value.function.isym->id;
285 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
286 fcn = gfc_build_intrinsic_call (current_ns, id,
287 fn->value.function.isym->name,
288 fn->where, 3, fcn, NULL, NULL);
289 else if (id == GFC_ISYM_ANY || id == GFC_ISYM_ALL)
290 fcn = gfc_build_intrinsic_call (current_ns, id,
291 fn->value.function.isym->name,
292 fn->where, 2, fcn, NULL);
293 else
294 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
296 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
299 return fcn;
302 /* Callback function for optimzation of reductions to scalars. Transform ANY
303 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
304 correspondingly. Handly only the simple cases without MASK and DIM. */
306 static int
307 callback_reduction (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
308 void *data ATTRIBUTE_UNUSED)
310 gfc_expr *fn, *arg;
311 gfc_intrinsic_op op;
312 gfc_isym_id id;
313 gfc_actual_arglist *a;
314 gfc_actual_arglist *dim;
315 gfc_constructor *c;
316 gfc_expr *res, *new_expr;
317 gfc_actual_arglist *mask;
319 fn = *e;
321 if (fn->rank != 0 || fn->expr_type != EXPR_FUNCTION
322 || fn->value.function.isym == NULL)
323 return 0;
325 id = fn->value.function.isym->id;
327 if (id != GFC_ISYM_SUM && id != GFC_ISYM_PRODUCT
328 && id != GFC_ISYM_ANY && id != GFC_ISYM_ALL)
329 return 0;
331 a = fn->value.function.actual;
333 /* Don't handle MASK or DIM. */
335 dim = a->next;
337 if (dim->expr != NULL)
338 return 0;
340 if (id == GFC_ISYM_SUM || id == GFC_ISYM_PRODUCT)
342 mask = dim->next;
343 if ( mask->expr != NULL)
344 return 0;
347 arg = a->expr;
349 if (arg->expr_type != EXPR_ARRAY)
350 return 0;
352 switch (id)
354 case GFC_ISYM_SUM:
355 op = INTRINSIC_PLUS;
356 break;
358 case GFC_ISYM_PRODUCT:
359 op = INTRINSIC_TIMES;
360 break;
362 case GFC_ISYM_ANY:
363 op = INTRINSIC_OR;
364 break;
366 case GFC_ISYM_ALL:
367 op = INTRINSIC_AND;
368 break;
370 default:
371 return 0;
374 c = gfc_constructor_first (arg->value.constructor);
376 /* Don't do any simplififcation if we have
377 - no element in the constructor or
378 - only have a single element in the array which contains an
379 iterator. */
381 if (c == NULL)
382 return 0;
384 res = copy_walk_reduction_arg (c, fn);
386 c = gfc_constructor_next (c);
387 while (c)
389 new_expr = gfc_get_expr ();
390 new_expr->ts = fn->ts;
391 new_expr->expr_type = EXPR_OP;
392 new_expr->rank = fn->rank;
393 new_expr->where = fn->where;
394 new_expr->value.op.op = op;
395 new_expr->value.op.op1 = res;
396 new_expr->value.op.op2 = copy_walk_reduction_arg (c, fn);
397 res = new_expr;
398 c = gfc_constructor_next (c);
401 gfc_simplify_expr (res, 0);
402 *e = res;
403 gfc_free_expr (fn);
405 return 0;
408 /* Callback function for common function elimination, called from cfe_expr_0.
409 Put all eligible function expressions into expr_array. */
411 static int
412 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
413 void *data ATTRIBUTE_UNUSED)
416 if ((*e)->expr_type != EXPR_FUNCTION)
417 return 0;
419 /* We don't do character functions with unknown charlens. */
420 if ((*e)->ts.type == BT_CHARACTER
421 && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
422 || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
423 return 0;
425 /* We don't do function elimination within FORALL statements, it can
426 lead to wrong-code in certain circumstances. */
428 if (forall_level > 0)
429 return 0;
431 /* Function elimination inside an iterator could lead to functions which
432 depend on iterator variables being moved outside. FIXME: We should check
433 if the functions do indeed depend on the iterator variable. */
435 if (iterator_level > 0)
436 return 0;
438 /* If we don't know the shape at compile time, we create an allocatable
439 temporary variable to hold the intermediate result, but only if
440 allocation on assignment is active. */
442 if ((*e)->rank > 0 && (*e)->shape == NULL && !flag_realloc_lhs)
443 return 0;
445 /* Skip the test for pure functions if -faggressive-function-elimination
446 is specified. */
447 if ((*e)->value.function.esym)
449 /* Don't create an array temporary for elemental functions. */
450 if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
451 return 0;
453 /* Only eliminate potentially impure functions if the
454 user specifically requested it. */
455 if (!flag_aggressive_function_elimination
456 && !(*e)->value.function.esym->attr.pure
457 && !(*e)->value.function.esym->attr.implicit_pure)
458 return 0;
461 if ((*e)->value.function.isym)
463 /* Conversions are handled on the fly by the middle end,
464 transpose during trans-* stages and TRANSFER by the middle end. */
465 if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
466 || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER
467 || gfc_inline_intrinsic_function_p (*e))
468 return 0;
470 /* Don't create an array temporary for elemental functions,
471 as this would be wasteful of memory.
472 FIXME: Create a scalar temporary during scalarization. */
473 if ((*e)->value.function.isym->elemental && (*e)->rank > 0)
474 return 0;
476 if (!(*e)->value.function.isym->pure)
477 return 0;
480 expr_array.safe_push (e);
481 return 0;
484 /* Auxiliary function to check if an expression is a temporary created by
485 create var. */
487 static bool
488 is_fe_temp (gfc_expr *e)
490 if (e->expr_type != EXPR_VARIABLE)
491 return false;
493 return e->symtree->n.sym->attr.fe_temp;
496 /* Determine the length of a string, if it can be evaluated as a constant
497 expression. Return a newly allocated gfc_expr or NULL on failure.
498 If the user specified a substring which is potentially longer than
499 the string itself, the string will be padded with spaces, which
500 is harmless. */
502 static gfc_expr *
503 constant_string_length (gfc_expr *e)
506 gfc_expr *length;
507 gfc_ref *ref;
508 gfc_expr *res;
509 mpz_t value;
511 if (e->ts.u.cl)
513 length = e->ts.u.cl->length;
514 if (length && length->expr_type == EXPR_CONSTANT)
515 return gfc_copy_expr(length);
518 /* Return length of substring, if constant. */
519 for (ref = e->ref; ref; ref = ref->next)
521 if (ref->type == REF_SUBSTRING
522 && gfc_dep_difference (ref->u.ss.end, ref->u.ss.start, &value))
524 res = gfc_get_constant_expr (BT_INTEGER, gfc_charlen_int_kind,
525 &e->where);
527 mpz_add_ui (res->value.integer, value, 1);
528 mpz_clear (value);
529 return res;
533 /* Return length of char symbol, if constant. */
535 if (e->symtree->n.sym->ts.u.cl && e->symtree->n.sym->ts.u.cl->length
536 && e->symtree->n.sym->ts.u.cl->length->expr_type == EXPR_CONSTANT)
537 return gfc_copy_expr (e->symtree->n.sym->ts.u.cl->length);
539 return NULL;
543 /* Insert a block at the current position unless it has already
544 been inserted; in this case use the one already there. */
546 static gfc_namespace*
547 insert_block ()
549 gfc_namespace *ns;
551 /* If the block hasn't already been created, do so. */
552 if (inserted_block == NULL)
554 inserted_block = XCNEW (gfc_code);
555 inserted_block->op = EXEC_BLOCK;
556 inserted_block->loc = (*current_code)->loc;
557 ns = gfc_build_block_ns (current_ns);
558 inserted_block->ext.block.ns = ns;
559 inserted_block->ext.block.assoc = NULL;
561 ns->code = *current_code;
563 /* If the statement has a label, make sure it is transferred to
564 the newly created block. */
566 if ((*current_code)->here)
568 inserted_block->here = (*current_code)->here;
569 (*current_code)->here = NULL;
572 inserted_block->next = (*current_code)->next;
573 changed_statement = &(inserted_block->ext.block.ns->code);
574 (*current_code)->next = NULL;
575 /* Insert the BLOCK at the right position. */
576 *current_code = inserted_block;
577 ns->parent = current_ns;
579 else
580 ns = inserted_block->ext.block.ns;
582 return ns;
585 /* Returns a new expression (a variable) to be used in place of the old one,
586 with an optional assignment statement before the current statement to set
587 the value of the variable. Creates a new BLOCK for the statement if that
588 hasn't already been done and puts the statement, plus the newly created
589 variables, in that block. Special cases: If the expression is constant or
590 a temporary which has already been created, just copy it. */
592 static gfc_expr*
593 create_var (gfc_expr * e, const char *vname)
595 char name[GFC_MAX_SYMBOL_LEN +1];
596 gfc_symtree *symtree;
597 gfc_symbol *symbol;
598 gfc_expr *result;
599 gfc_code *n;
600 gfc_namespace *ns;
601 int i;
603 if (e->expr_type == EXPR_CONSTANT || is_fe_temp (e))
604 return gfc_copy_expr (e);
606 ns = insert_block ();
608 if (vname)
609 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d_%s", var_num++, vname);
610 else
611 snprintf (name, GFC_MAX_SYMBOL_LEN, "__var_%d", var_num++);
613 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
614 gcc_unreachable ();
616 symbol = symtree->n.sym;
617 symbol->ts = e->ts;
619 if (e->rank > 0)
621 symbol->as = gfc_get_array_spec ();
622 symbol->as->rank = e->rank;
624 if (e->shape == NULL)
626 /* We don't know the shape at compile time, so we use an
627 allocatable. */
628 symbol->as->type = AS_DEFERRED;
629 symbol->attr.allocatable = 1;
631 else
633 symbol->as->type = AS_EXPLICIT;
634 /* Copy the shape. */
635 for (i=0; i<e->rank; i++)
637 gfc_expr *p, *q;
639 p = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
640 &(e->where));
641 mpz_set_si (p->value.integer, 1);
642 symbol->as->lower[i] = p;
644 q = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
645 &(e->where));
646 mpz_set (q->value.integer, e->shape[i]);
647 symbol->as->upper[i] = q;
652 if (e->ts.type == BT_CHARACTER && e->rank == 0)
654 gfc_expr *length;
656 length = constant_string_length (e);
657 if (length)
659 symbol->ts.u.cl = gfc_new_charlen (ns, NULL);
660 symbol->ts.u.cl->length = length;
662 else
663 symbol->attr.allocatable = 1;
666 symbol->attr.flavor = FL_VARIABLE;
667 symbol->attr.referenced = 1;
668 symbol->attr.dimension = e->rank > 0;
669 symbol->attr.fe_temp = 1;
670 gfc_commit_symbol (symbol);
672 result = gfc_get_expr ();
673 result->expr_type = EXPR_VARIABLE;
674 result->ts = e->ts;
675 result->rank = e->rank;
676 result->shape = gfc_copy_shape (e->shape, e->rank);
677 result->symtree = symtree;
678 result->where = e->where;
679 if (e->rank > 0)
681 result->ref = gfc_get_ref ();
682 result->ref->type = REF_ARRAY;
683 result->ref->u.ar.type = AR_FULL;
684 result->ref->u.ar.where = e->where;
685 result->ref->u.ar.dimen = e->rank;
686 result->ref->u.ar.as = symbol->ts.type == BT_CLASS
687 ? CLASS_DATA (symbol)->as : symbol->as;
688 if (warn_array_temporaries)
689 gfc_warning (OPT_Warray_temporaries,
690 "Creating array temporary at %L", &(e->where));
693 /* Generate the new assignment. */
694 n = XCNEW (gfc_code);
695 n->op = EXEC_ASSIGN;
696 n->loc = (*current_code)->loc;
697 n->next = *changed_statement;
698 n->expr1 = gfc_copy_expr (result);
699 n->expr2 = e;
700 *changed_statement = n;
701 n_vars ++;
703 return result;
706 /* Warn about function elimination. */
708 static void
709 do_warn_function_elimination (gfc_expr *e)
711 if (e->expr_type != EXPR_FUNCTION)
712 return;
713 if (e->value.function.esym)
714 gfc_warning (0, "Removing call to function %qs at %L",
715 e->value.function.esym->name, &(e->where));
716 else if (e->value.function.isym)
717 gfc_warning (0, "Removing call to function %qs at %L",
718 e->value.function.isym->name, &(e->where));
720 /* Callback function for the code walker for doing common function
721 elimination. This builds up the list of functions in the expression
722 and goes through them to detect duplicates, which it then replaces
723 by variables. */
725 static int
726 cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
727 void *data ATTRIBUTE_UNUSED)
729 int i,j;
730 gfc_expr *newvar;
731 gfc_expr **ei, **ej;
733 /* Don't do this optimization within OMP workshare. */
735 if (in_omp_workshare)
737 *walk_subtrees = 0;
738 return 0;
741 expr_array.release ();
743 gfc_expr_walker (e, cfe_register_funcs, NULL);
745 /* Walk through all the functions. */
747 FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
749 /* Skip if the function has been replaced by a variable already. */
750 if ((*ei)->expr_type == EXPR_VARIABLE)
751 continue;
753 newvar = NULL;
754 for (j=0; j<i; j++)
756 ej = expr_array[j];
757 if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
759 if (newvar == NULL)
760 newvar = create_var (*ei, "fcn");
762 if (warn_function_elimination)
763 do_warn_function_elimination (*ej);
765 free (*ej);
766 *ej = gfc_copy_expr (newvar);
769 if (newvar)
770 *ei = newvar;
773 /* We did all the necessary walking in this function. */
774 *walk_subtrees = 0;
775 return 0;
778 /* Callback function for common function elimination, called from
779 gfc_code_walker. This keeps track of the current code, in order
780 to insert statements as needed. */
782 static int
783 cfe_code (gfc_code **c, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
785 current_code = c;
786 inserted_block = NULL;
787 changed_statement = NULL;
789 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
790 and allocation on assigment are prohibited inside WHERE, and finally
791 masking an expression would lead to wrong-code when replacing
793 WHERE (a>0)
794 b = sum(foo(a) + foo(a))
795 END WHERE
797 with
799 WHERE (a > 0)
800 tmp = foo(a)
801 b = sum(tmp + tmp)
802 END WHERE
805 if ((*c)->op == EXEC_WHERE)
807 *walk_subtrees = 0;
808 return 0;
812 return 0;
815 /* Dummy function for expression call back, for use when we
816 really don't want to do any walking. */
818 static int
819 dummy_expr_callback (gfc_expr **e ATTRIBUTE_UNUSED, int *walk_subtrees,
820 void *data ATTRIBUTE_UNUSED)
822 *walk_subtrees = 0;
823 return 0;
826 /* Dummy function for code callback, for use when we really
827 don't want to do anything. */
829 gfc_dummy_code_callback (gfc_code **e ATTRIBUTE_UNUSED,
830 int *walk_subtrees ATTRIBUTE_UNUSED,
831 void *data ATTRIBUTE_UNUSED)
833 return 0;
836 /* Code callback function for converting
837 do while(a)
838 end do
839 into the equivalent
841 if (.not. a) exit
842 end do
843 This is because common function elimination would otherwise place the
844 temporary variables outside the loop. */
846 static int
847 convert_do_while (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
848 void *data ATTRIBUTE_UNUSED)
850 gfc_code *co = *c;
851 gfc_code *c_if1, *c_if2, *c_exit;
852 gfc_code *loopblock;
853 gfc_expr *e_not, *e_cond;
855 if (co->op != EXEC_DO_WHILE)
856 return 0;
858 if (co->expr1 == NULL || co->expr1->expr_type == EXPR_CONSTANT)
859 return 0;
861 e_cond = co->expr1;
863 /* Generate the condition of the if statement, which is .not. the original
864 statement. */
865 e_not = gfc_get_expr ();
866 e_not->ts = e_cond->ts;
867 e_not->where = e_cond->where;
868 e_not->expr_type = EXPR_OP;
869 e_not->value.op.op = INTRINSIC_NOT;
870 e_not->value.op.op1 = e_cond;
872 /* Generate the EXIT statement. */
873 c_exit = XCNEW (gfc_code);
874 c_exit->op = EXEC_EXIT;
875 c_exit->ext.which_construct = co;
876 c_exit->loc = co->loc;
878 /* Generate the IF statement. */
879 c_if2 = XCNEW (gfc_code);
880 c_if2->op = EXEC_IF;
881 c_if2->expr1 = e_not;
882 c_if2->next = c_exit;
883 c_if2->loc = co->loc;
885 /* ... plus the one to chain it to. */
886 c_if1 = XCNEW (gfc_code);
887 c_if1->op = EXEC_IF;
888 c_if1->block = c_if2;
889 c_if1->loc = co->loc;
891 /* Make the DO WHILE loop into a DO block by replacing the condition
892 with a true constant. */
893 co->expr1 = gfc_get_logical_expr (gfc_default_integer_kind, &co->loc, true);
895 /* Hang the generated if statement into the loop body. */
897 loopblock = co->block->next;
898 co->block->next = c_if1;
899 c_if1->next = loopblock;
901 return 0;
904 /* Code callback function for converting
905 if (a) then
907 else if (b) then
908 end if
910 into
911 if (a) then
912 else
913 if (b) then
914 end if
915 end if
917 because otherwise common function elimination would place the BLOCKs
918 into the wrong place. */
920 static int
921 convert_elseif (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
922 void *data ATTRIBUTE_UNUSED)
924 gfc_code *co = *c;
925 gfc_code *c_if1, *c_if2, *else_stmt;
927 if (co->op != EXEC_IF)
928 return 0;
930 /* This loop starts out with the first ELSE statement. */
931 else_stmt = co->block->block;
933 while (else_stmt != NULL)
935 gfc_code *next_else;
937 /* If there is no condition, we're done. */
938 if (else_stmt->expr1 == NULL)
939 break;
941 next_else = else_stmt->block;
943 /* Generate the new IF statement. */
944 c_if2 = XCNEW (gfc_code);
945 c_if2->op = EXEC_IF;
946 c_if2->expr1 = else_stmt->expr1;
947 c_if2->next = else_stmt->next;
948 c_if2->loc = else_stmt->loc;
949 c_if2->block = next_else;
951 /* ... plus the one to chain it to. */
952 c_if1 = XCNEW (gfc_code);
953 c_if1->op = EXEC_IF;
954 c_if1->block = c_if2;
955 c_if1->loc = else_stmt->loc;
957 /* Insert the new IF after the ELSE. */
958 else_stmt->expr1 = NULL;
959 else_stmt->next = c_if1;
960 else_stmt->block = NULL;
962 else_stmt = next_else;
964 /* Don't walk subtrees. */
965 return 0;
968 /* Optimize a namespace, including all contained namespaces. */
970 static void
971 optimize_namespace (gfc_namespace *ns)
973 gfc_namespace *saved_ns = gfc_current_ns;
974 current_ns = ns;
975 gfc_current_ns = ns;
976 forall_level = 0;
977 iterator_level = 0;
978 in_assoc_list = false;
979 in_omp_workshare = false;
981 gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
982 gfc_code_walker (&ns->code, convert_elseif, dummy_expr_callback, NULL);
983 gfc_code_walker (&ns->code, cfe_code, cfe_expr_0, NULL);
984 gfc_code_walker (&ns->code, optimize_code, optimize_expr, NULL);
985 if (flag_inline_matmul_limit != 0)
986 gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
987 NULL);
989 /* BLOCKs are handled in the expression walker below. */
990 for (ns = ns->contained; ns; ns = ns->sibling)
992 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
993 optimize_namespace (ns);
995 gfc_current_ns = saved_ns;
998 /* Handle dependencies for allocatable strings which potentially redefine
999 themselves in an assignment. */
1001 static void
1002 realloc_strings (gfc_namespace *ns)
1004 current_ns = ns;
1005 gfc_code_walker (&ns->code, realloc_string_callback, dummy_expr_callback, NULL);
1007 for (ns = ns->contained; ns; ns = ns->sibling)
1009 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1010 realloc_strings (ns);
1015 static void
1016 optimize_reduction (gfc_namespace *ns)
1018 current_ns = ns;
1019 gfc_code_walker (&ns->code, gfc_dummy_code_callback,
1020 callback_reduction, NULL);
1022 /* BLOCKs are handled in the expression walker below. */
1023 for (ns = ns->contained; ns; ns = ns->sibling)
1025 if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
1026 optimize_reduction (ns);
1030 /* Replace code like
1031 a = matmul(b,c) + d
1032 with
1033 a = matmul(b,c) ; a = a + d
1034 where the array function is not elemental and not allocatable
1035 and does not depend on the left-hand side.
1038 static bool
1039 optimize_binop_array_assignment (gfc_code *c, gfc_expr **rhs, bool seen_op)
1041 gfc_expr *e;
1043 e = *rhs;
1044 if (e->expr_type == EXPR_OP)
1046 switch (e->value.op.op)
1048 /* Unary operators and exponentiation: Only look at a single
1049 operand. */
1050 case INTRINSIC_NOT:
1051 case INTRINSIC_UPLUS:
1052 case INTRINSIC_UMINUS:
1053 case INTRINSIC_PARENTHESES:
1054 case INTRINSIC_POWER:
1055 if (optimize_binop_array_assignment (c, &e->value.op.op1, seen_op))
1056 return true;
1057 break;
1059 case INTRINSIC_CONCAT:
1060 /* Do not do string concatenations. */
1061 break;
1063 default:
1064 /* Binary operators. */
1065 if (optimize_binop_array_assignment (c, &e->value.op.op1, true))
1066 return true;
1068 if (optimize_binop_array_assignment (c, &e->value.op.op2, true))
1069 return true;
1071 break;
1074 else if (seen_op && e->expr_type == EXPR_FUNCTION && e->rank > 0
1075 && ! (e->value.function.esym
1076 && (e->value.function.esym->attr.elemental
1077 || e->value.function.esym->attr.allocatable
1078 || e->value.function.esym->ts.type != c->expr1->ts.type
1079 || e->value.function.esym->ts.kind != c->expr1->ts.kind))
1080 && ! (e->value.function.isym
1081 && (e->value.function.isym->elemental
1082 || e->ts.type != c->expr1->ts.type
1083 || e->ts.kind != c->expr1->ts.kind))
1084 && ! gfc_inline_intrinsic_function_p (e))
1087 gfc_code *n;
1088 gfc_expr *new_expr;
1090 /* Insert a new assignment statement after the current one. */
1091 n = XCNEW (gfc_code);
1092 n->op = EXEC_ASSIGN;
1093 n->loc = c->loc;
1094 n->next = c->next;
1095 c->next = n;
1097 n->expr1 = gfc_copy_expr (c->expr1);
1098 n->expr2 = c->expr2;
1099 new_expr = gfc_copy_expr (c->expr1);
1100 c->expr2 = e;
1101 *rhs = new_expr;
1103 return true;
1107 /* Nothing to optimize. */
1108 return false;
1111 /* Remove unneeded TRIMs at the end of expressions. */
1113 static bool
1114 remove_trim (gfc_expr *rhs)
1116 bool ret;
1118 ret = false;
1120 /* Check for a // b // trim(c). Looping is probably not
1121 necessary because the parser usually generates
1122 (// (// a b ) trim(c) ) , but better safe than sorry. */
1124 while (rhs->expr_type == EXPR_OP
1125 && rhs->value.op.op == INTRINSIC_CONCAT)
1126 rhs = rhs->value.op.op2;
1128 while (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym
1129 && rhs->value.function.isym->id == GFC_ISYM_TRIM)
1131 strip_function_call (rhs);
1132 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1133 remove_trim (rhs);
1134 ret = true;
1137 return ret;
1140 /* Optimizations for an assignment. */
1142 static void
1143 optimize_assignment (gfc_code * c)
1145 gfc_expr *lhs, *rhs;
1147 lhs = c->expr1;
1148 rhs = c->expr2;
1150 if (lhs->ts.type == BT_CHARACTER && !lhs->ts.deferred)
1152 /* Optimize a = trim(b) to a = b. */
1153 remove_trim (rhs);
1155 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1156 if (is_empty_string (rhs))
1157 rhs->value.character.length = 0;
1160 if (lhs->rank > 0 && gfc_check_dependency (lhs, rhs, true) == 0)
1161 optimize_binop_array_assignment (c, &rhs, false);
1165 /* Remove an unneeded function call, modifying the expression.
1166 This replaces the function call with the value of its
1167 first argument. The rest of the argument list is freed. */
1169 static void
1170 strip_function_call (gfc_expr *e)
1172 gfc_expr *e1;
1173 gfc_actual_arglist *a;
1175 a = e->value.function.actual;
1177 /* We should have at least one argument. */
1178 gcc_assert (a->expr != NULL);
1180 e1 = a->expr;
1182 /* Free the remaining arglist, if any. */
1183 if (a->next)
1184 gfc_free_actual_arglist (a->next);
1186 /* Graft the argument expression onto the original function. */
1187 *e = *e1;
1188 free (e1);
1192 /* Optimization of lexical comparison functions. */
1194 static bool
1195 optimize_lexical_comparison (gfc_expr *e)
1197 if (e->expr_type != EXPR_FUNCTION || e->value.function.isym == NULL)
1198 return false;
1200 switch (e->value.function.isym->id)
1202 case GFC_ISYM_LLE:
1203 return optimize_comparison (e, INTRINSIC_LE);
1205 case GFC_ISYM_LGE:
1206 return optimize_comparison (e, INTRINSIC_GE);
1208 case GFC_ISYM_LGT:
1209 return optimize_comparison (e, INTRINSIC_GT);
1211 case GFC_ISYM_LLT:
1212 return optimize_comparison (e, INTRINSIC_LT);
1214 default:
1215 break;
1217 return false;
1220 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1221 do CHARACTER because of possible pessimization involving character
1222 lengths. */
1224 static bool
1225 combine_array_constructor (gfc_expr *e)
1228 gfc_expr *op1, *op2;
1229 gfc_expr *scalar;
1230 gfc_expr *new_expr;
1231 gfc_constructor *c, *new_c;
1232 gfc_constructor_base oldbase, newbase;
1233 bool scalar_first;
1235 /* Array constructors have rank one. */
1236 if (e->rank != 1)
1237 return false;
1239 /* Don't try to combine association lists, this makes no sense
1240 and leads to an ICE. */
1241 if (in_assoc_list)
1242 return false;
1244 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1245 if (forall_level > 0)
1246 return false;
1248 op1 = e->value.op.op1;
1249 op2 = e->value.op.op2;
1251 if (op1->expr_type == EXPR_ARRAY && op2->rank == 0)
1252 scalar_first = false;
1253 else if (op2->expr_type == EXPR_ARRAY && op1->rank == 0)
1255 scalar_first = true;
1256 op1 = e->value.op.op2;
1257 op2 = e->value.op.op1;
1259 else
1260 return false;
1262 if (op2->ts.type == BT_CHARACTER)
1263 return false;
1265 scalar = create_var (gfc_copy_expr (op2), "constr");
1267 oldbase = op1->value.constructor;
1268 newbase = NULL;
1269 e->expr_type = EXPR_ARRAY;
1271 for (c = gfc_constructor_first (oldbase); c;
1272 c = gfc_constructor_next (c))
1274 new_expr = gfc_get_expr ();
1275 new_expr->ts = e->ts;
1276 new_expr->expr_type = EXPR_OP;
1277 new_expr->rank = c->expr->rank;
1278 new_expr->where = c->where;
1279 new_expr->value.op.op = e->value.op.op;
1281 if (scalar_first)
1283 new_expr->value.op.op1 = gfc_copy_expr (scalar);
1284 new_expr->value.op.op2 = gfc_copy_expr (c->expr);
1286 else
1288 new_expr->value.op.op1 = gfc_copy_expr (c->expr);
1289 new_expr->value.op.op2 = gfc_copy_expr (scalar);
1292 new_c = gfc_constructor_append_expr (&newbase, new_expr, &(e->where));
1293 new_c->iterator = c->iterator;
1294 c->iterator = NULL;
1297 gfc_free_expr (op1);
1298 gfc_free_expr (op2);
1299 gfc_free_expr (scalar);
1301 e->value.constructor = newbase;
1302 return true;
1305 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1306 2**k into ishift(1,k) */
1308 static bool
1309 optimize_power (gfc_expr *e)
1311 gfc_expr *op1, *op2;
1312 gfc_expr *iand, *ishft;
1314 if (e->ts.type != BT_INTEGER)
1315 return false;
1317 op1 = e->value.op.op1;
1319 if (op1 == NULL || op1->expr_type != EXPR_CONSTANT)
1320 return false;
1322 if (mpz_cmp_si (op1->value.integer, -1L) == 0)
1324 gfc_free_expr (op1);
1326 op2 = e->value.op.op2;
1328 if (op2 == NULL)
1329 return false;
1331 iand = gfc_build_intrinsic_call (current_ns, GFC_ISYM_IAND,
1332 "_internal_iand", e->where, 2, op2,
1333 gfc_get_int_expr (e->ts.kind,
1334 &e->where, 1));
1336 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1337 "_internal_ishft", e->where, 2, iand,
1338 gfc_get_int_expr (e->ts.kind,
1339 &e->where, 1));
1341 e->value.op.op = INTRINSIC_MINUS;
1342 e->value.op.op1 = gfc_get_int_expr (e->ts.kind, &e->where, 1);
1343 e->value.op.op2 = ishft;
1344 return true;
1346 else if (mpz_cmp_si (op1->value.integer, 2L) == 0)
1348 gfc_free_expr (op1);
1350 op2 = e->value.op.op2;
1351 if (op2 == NULL)
1352 return false;
1354 ishft = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ISHFT,
1355 "_internal_ishft", e->where, 2,
1356 gfc_get_int_expr (e->ts.kind,
1357 &e->where, 1),
1358 op2);
1359 *e = *ishft;
1360 return true;
1363 else if (mpz_cmp_si (op1->value.integer, 1L) == 0)
1365 op2 = e->value.op.op2;
1366 if (op2 == NULL)
1367 return false;
1369 gfc_free_expr (op1);
1370 gfc_free_expr (op2);
1372 e->expr_type = EXPR_CONSTANT;
1373 e->value.op.op1 = NULL;
1374 e->value.op.op2 = NULL;
1375 mpz_init_set_si (e->value.integer, 1);
1376 /* Typespec and location are still OK. */
1377 return true;
1380 return false;
1383 /* Recursive optimization of operators. */
1385 static bool
1386 optimize_op (gfc_expr *e)
1388 bool changed;
1390 gfc_intrinsic_op op = e->value.op.op;
1392 changed = false;
1394 /* Only use new-style comparisons. */
1395 switch(op)
1397 case INTRINSIC_EQ_OS:
1398 op = INTRINSIC_EQ;
1399 break;
1401 case INTRINSIC_GE_OS:
1402 op = INTRINSIC_GE;
1403 break;
1405 case INTRINSIC_LE_OS:
1406 op = INTRINSIC_LE;
1407 break;
1409 case INTRINSIC_NE_OS:
1410 op = INTRINSIC_NE;
1411 break;
1413 case INTRINSIC_GT_OS:
1414 op = INTRINSIC_GT;
1415 break;
1417 case INTRINSIC_LT_OS:
1418 op = INTRINSIC_LT;
1419 break;
1421 default:
1422 break;
1425 switch (op)
1427 case INTRINSIC_EQ:
1428 case INTRINSIC_GE:
1429 case INTRINSIC_LE:
1430 case INTRINSIC_NE:
1431 case INTRINSIC_GT:
1432 case INTRINSIC_LT:
1433 changed = optimize_comparison (e, op);
1435 /* Fall through */
1436 /* Look at array constructors. */
1437 case INTRINSIC_PLUS:
1438 case INTRINSIC_MINUS:
1439 case INTRINSIC_TIMES:
1440 case INTRINSIC_DIVIDE:
1441 return combine_array_constructor (e) || changed;
1443 case INTRINSIC_POWER:
1444 return optimize_power (e);
1445 break;
1447 default:
1448 break;
1451 return false;
1455 /* Return true if a constant string contains only blanks. */
1457 static bool
1458 is_empty_string (gfc_expr *e)
1460 int i;
1462 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_CONSTANT)
1463 return false;
1465 for (i=0; i < e->value.character.length; i++)
1467 if (e->value.character.string[i] != ' ')
1468 return false;
1471 return true;
1475 /* Insert a call to the intrinsic len_trim. Use a different name for
1476 the symbol tree so we don't run into trouble when the user has
1477 renamed len_trim for some reason. */
1479 static gfc_expr*
1480 get_len_trim_call (gfc_expr *str, int kind)
1482 gfc_expr *fcn;
1483 gfc_actual_arglist *actual_arglist, *next;
1485 fcn = gfc_get_expr ();
1486 fcn->expr_type = EXPR_FUNCTION;
1487 fcn->value.function.isym = gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM);
1488 actual_arglist = gfc_get_actual_arglist ();
1489 actual_arglist->expr = str;
1490 next = gfc_get_actual_arglist ();
1491 next->expr = gfc_get_int_expr (gfc_default_integer_kind, NULL, kind);
1492 actual_arglist->next = next;
1494 fcn->value.function.actual = actual_arglist;
1495 fcn->where = str->where;
1496 fcn->ts.type = BT_INTEGER;
1497 fcn->ts.kind = gfc_charlen_int_kind;
1499 gfc_get_sym_tree ("__internal_len_trim", current_ns, &fcn->symtree, false);
1500 fcn->symtree->n.sym->ts = fcn->ts;
1501 fcn->symtree->n.sym->attr.flavor = FL_PROCEDURE;
1502 fcn->symtree->n.sym->attr.function = 1;
1503 fcn->symtree->n.sym->attr.elemental = 1;
1504 fcn->symtree->n.sym->attr.referenced = 1;
1505 fcn->symtree->n.sym->attr.access = ACCESS_PRIVATE;
1506 gfc_commit_symbol (fcn->symtree->n.sym);
1508 return fcn;
1511 /* Optimize expressions for equality. */
1513 static bool
1514 optimize_comparison (gfc_expr *e, gfc_intrinsic_op op)
1516 gfc_expr *op1, *op2;
1517 bool change;
1518 int eq;
1519 bool result;
1520 gfc_actual_arglist *firstarg, *secondarg;
1522 if (e->expr_type == EXPR_OP)
1524 firstarg = NULL;
1525 secondarg = NULL;
1526 op1 = e->value.op.op1;
1527 op2 = e->value.op.op2;
1529 else if (e->expr_type == EXPR_FUNCTION)
1531 /* One of the lexical comparison functions. */
1532 firstarg = e->value.function.actual;
1533 secondarg = firstarg->next;
1534 op1 = firstarg->expr;
1535 op2 = secondarg->expr;
1537 else
1538 gcc_unreachable ();
1540 /* Strip off unneeded TRIM calls from string comparisons. */
1542 change = remove_trim (op1);
1544 if (remove_trim (op2))
1545 change = true;
1547 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
1548 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
1549 handles them well). However, there are also cases that need a non-scalar
1550 argument. For example the any intrinsic. See PR 45380. */
1551 if (e->rank > 0)
1552 return change;
1554 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
1555 len_trim(a) != 0 */
1556 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
1557 && (op == INTRINSIC_EQ || op == INTRINSIC_NE))
1559 bool empty_op1, empty_op2;
1560 empty_op1 = is_empty_string (op1);
1561 empty_op2 = is_empty_string (op2);
1563 if (empty_op1 || empty_op2)
1565 gfc_expr *fcn;
1566 gfc_expr *zero;
1567 gfc_expr *str;
1569 /* This can only happen when an error for comparing
1570 characters of different kinds has already been issued. */
1571 if (empty_op1 && empty_op2)
1572 return false;
1574 zero = gfc_get_int_expr (gfc_charlen_int_kind, &e->where, 0);
1575 str = empty_op1 ? op2 : op1;
1577 fcn = get_len_trim_call (str, gfc_charlen_int_kind);
1580 if (empty_op1)
1581 gfc_free_expr (op1);
1582 else
1583 gfc_free_expr (op2);
1585 op1 = fcn;
1586 op2 = zero;
1587 e->value.op.op1 = fcn;
1588 e->value.op.op2 = zero;
1593 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
1595 if (flag_finite_math_only
1596 || (op1->ts.type != BT_REAL && op2->ts.type != BT_REAL
1597 && op1->ts.type != BT_COMPLEX && op2->ts.type != BT_COMPLEX))
1599 eq = gfc_dep_compare_expr (op1, op2);
1600 if (eq <= -2)
1602 /* Replace A // B < A // C with B < C, and A // B < C // B
1603 with A < C. */
1604 if (op1->ts.type == BT_CHARACTER && op2->ts.type == BT_CHARACTER
1605 && op1->expr_type == EXPR_OP
1606 && op1->value.op.op == INTRINSIC_CONCAT
1607 && op2->expr_type == EXPR_OP
1608 && op2->value.op.op == INTRINSIC_CONCAT)
1610 gfc_expr *op1_left = op1->value.op.op1;
1611 gfc_expr *op2_left = op2->value.op.op1;
1612 gfc_expr *op1_right = op1->value.op.op2;
1613 gfc_expr *op2_right = op2->value.op.op2;
1615 if (gfc_dep_compare_expr (op1_left, op2_left) == 0)
1617 /* Watch out for 'A ' // x vs. 'A' // x. */
1619 if (op1_left->expr_type == EXPR_CONSTANT
1620 && op2_left->expr_type == EXPR_CONSTANT
1621 && op1_left->value.character.length
1622 != op2_left->value.character.length)
1623 return change;
1624 else
1626 free (op1_left);
1627 free (op2_left);
1628 if (firstarg)
1630 firstarg->expr = op1_right;
1631 secondarg->expr = op2_right;
1633 else
1635 e->value.op.op1 = op1_right;
1636 e->value.op.op2 = op2_right;
1638 optimize_comparison (e, op);
1639 return true;
1642 if (gfc_dep_compare_expr (op1_right, op2_right) == 0)
1644 free (op1_right);
1645 free (op2_right);
1646 if (firstarg)
1648 firstarg->expr = op1_left;
1649 secondarg->expr = op2_left;
1651 else
1653 e->value.op.op1 = op1_left;
1654 e->value.op.op2 = op2_left;
1657 optimize_comparison (e, op);
1658 return true;
1662 else
1664 /* eq can only be -1, 0 or 1 at this point. */
1665 switch (op)
1667 case INTRINSIC_EQ:
1668 result = eq == 0;
1669 break;
1671 case INTRINSIC_GE:
1672 result = eq >= 0;
1673 break;
1675 case INTRINSIC_LE:
1676 result = eq <= 0;
1677 break;
1679 case INTRINSIC_NE:
1680 result = eq != 0;
1681 break;
1683 case INTRINSIC_GT:
1684 result = eq > 0;
1685 break;
1687 case INTRINSIC_LT:
1688 result = eq < 0;
1689 break;
1691 default:
1692 gfc_internal_error ("illegal OP in optimize_comparison");
1693 break;
1696 /* Replace the expression by a constant expression. The typespec
1697 and where remains the way it is. */
1698 free (op1);
1699 free (op2);
1700 e->expr_type = EXPR_CONSTANT;
1701 e->value.logical = result;
1702 return true;
1706 return change;
1709 /* Optimize a trim function by replacing it with an equivalent substring
1710 involving a call to len_trim. This only works for expressions where
1711 variables are trimmed. Return true if anything was modified. */
1713 static bool
1714 optimize_trim (gfc_expr *e)
1716 gfc_expr *a;
1717 gfc_ref *ref;
1718 gfc_expr *fcn;
1719 gfc_ref **rr = NULL;
1721 /* Don't do this optimization within an argument list, because
1722 otherwise aliasing issues may occur. */
1724 if (count_arglist != 1)
1725 return false;
1727 if (e->ts.type != BT_CHARACTER || e->expr_type != EXPR_FUNCTION
1728 || e->value.function.isym == NULL
1729 || e->value.function.isym->id != GFC_ISYM_TRIM)
1730 return false;
1732 a = e->value.function.actual->expr;
1734 if (a->expr_type != EXPR_VARIABLE)
1735 return false;
1737 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
1739 if (a->symtree->n.sym->attr.allocatable)
1740 return false;
1742 /* Follow all references to find the correct place to put the newly
1743 created reference. FIXME: Also handle substring references and
1744 array references. Array references cause strange regressions at
1745 the moment. */
1747 if (a->ref)
1749 for (rr = &(a->ref); *rr; rr = &((*rr)->next))
1751 if ((*rr)->type == REF_SUBSTRING || (*rr)->type == REF_ARRAY)
1752 return false;
1756 strip_function_call (e);
1758 if (e->ref == NULL)
1759 rr = &(e->ref);
1761 /* Create the reference. */
1763 ref = gfc_get_ref ();
1764 ref->type = REF_SUBSTRING;
1766 /* Set the start of the reference. */
1768 ref->u.ss.start = gfc_get_int_expr (gfc_default_integer_kind, NULL, 1);
1770 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
1772 fcn = get_len_trim_call (gfc_copy_expr (e), gfc_default_integer_kind);
1774 /* Set the end of the reference to the call to len_trim. */
1776 ref->u.ss.end = fcn;
1777 gcc_assert (rr != NULL && *rr == NULL);
1778 *rr = ref;
1779 return true;
1782 /* Optimize minloc(b), where b is rank 1 array, into
1783 (/ minloc(b, dim=1) /), and similarly for maxloc,
1784 as the latter forms are expanded inline. */
1786 static void
1787 optimize_minmaxloc (gfc_expr **e)
1789 gfc_expr *fn = *e;
1790 gfc_actual_arglist *a;
1791 char *name, *p;
1793 if (fn->rank != 1
1794 || fn->value.function.actual == NULL
1795 || fn->value.function.actual->expr == NULL
1796 || fn->value.function.actual->expr->rank != 1)
1797 return;
1799 *e = gfc_get_array_expr (fn->ts.type, fn->ts.kind, &fn->where);
1800 (*e)->shape = fn->shape;
1801 fn->rank = 0;
1802 fn->shape = NULL;
1803 gfc_constructor_append_expr (&(*e)->value.constructor, fn, &fn->where);
1805 name = XALLOCAVEC (char, strlen (fn->value.function.name) + 1);
1806 strcpy (name, fn->value.function.name);
1807 p = strstr (name, "loc0");
1808 p[3] = '1';
1809 fn->value.function.name = gfc_get_string (name);
1810 if (fn->value.function.actual->next)
1812 a = fn->value.function.actual->next;
1813 gcc_assert (a->expr == NULL);
1815 else
1817 a = gfc_get_actual_arglist ();
1818 fn->value.function.actual->next = a;
1820 a->expr = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
1821 &fn->where);
1822 mpz_set_ui (a->expr->value.integer, 1);
1825 /* Callback function for code checking that we do not pass a DO variable to an
1826 INTENT(OUT) or INTENT(INOUT) dummy variable. */
1828 static int
1829 doloop_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
1830 void *data ATTRIBUTE_UNUSED)
1832 gfc_code *co;
1833 int i;
1834 gfc_formal_arglist *f;
1835 gfc_actual_arglist *a;
1836 gfc_code *cl;
1838 co = *c;
1840 /* If the doloop_list grew, we have to truncate it here. */
1842 if ((unsigned) doloop_level < doloop_list.length())
1843 doloop_list.truncate (doloop_level);
1845 switch (co->op)
1847 case EXEC_DO:
1849 if (co->ext.iterator && co->ext.iterator->var)
1850 doloop_list.safe_push (co);
1851 else
1852 doloop_list.safe_push ((gfc_code *) NULL);
1853 break;
1855 case EXEC_CALL:
1857 if (co->resolved_sym == NULL)
1858 break;
1860 f = gfc_sym_get_dummy_args (co->resolved_sym);
1862 /* Withot a formal arglist, there is only unknown INTENT,
1863 which we don't check for. */
1864 if (f == NULL)
1865 break;
1867 a = co->ext.actual;
1869 while (a && f)
1871 FOR_EACH_VEC_ELT (doloop_list, i, cl)
1873 gfc_symbol *do_sym;
1875 if (cl == NULL)
1876 break;
1878 do_sym = cl->ext.iterator->var->symtree->n.sym;
1880 if (a->expr && a->expr->symtree
1881 && a->expr->symtree->n.sym == do_sym)
1883 if (f->sym->attr.intent == INTENT_OUT)
1884 gfc_error_now ("Variable %qs at %L set to undefined "
1885 "value inside loop beginning at %L as "
1886 "INTENT(OUT) argument to subroutine %qs",
1887 do_sym->name, &a->expr->where,
1888 &doloop_list[i]->loc,
1889 co->symtree->n.sym->name);
1890 else if (f->sym->attr.intent == INTENT_INOUT)
1891 gfc_error_now ("Variable %qs at %L not definable inside "
1892 "loop beginning at %L as INTENT(INOUT) "
1893 "argument to subroutine %qs",
1894 do_sym->name, &a->expr->where,
1895 &doloop_list[i]->loc,
1896 co->symtree->n.sym->name);
1899 a = a->next;
1900 f = f->next;
1902 break;
1904 default:
1905 break;
1907 return 0;
1910 /* Callback function for functions checking that we do not pass a DO variable
1911 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
1913 static int
1914 do_function (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
1915 void *data ATTRIBUTE_UNUSED)
1917 gfc_formal_arglist *f;
1918 gfc_actual_arglist *a;
1919 gfc_expr *expr;
1920 gfc_code *dl;
1921 int i;
1923 expr = *e;
1924 if (expr->expr_type != EXPR_FUNCTION)
1925 return 0;
1927 /* Intrinsic functions don't modify their arguments. */
1929 if (expr->value.function.isym)
1930 return 0;
1932 f = gfc_sym_get_dummy_args (expr->symtree->n.sym);
1934 /* Without a formal arglist, there is only unknown INTENT,
1935 which we don't check for. */
1936 if (f == NULL)
1937 return 0;
1939 a = expr->value.function.actual;
1941 while (a && f)
1943 FOR_EACH_VEC_ELT (doloop_list, i, dl)
1945 gfc_symbol *do_sym;
1947 if (dl == NULL)
1948 break;
1950 do_sym = dl->ext.iterator->var->symtree->n.sym;
1952 if (a->expr && a->expr->symtree
1953 && a->expr->symtree->n.sym == do_sym)
1955 if (f->sym->attr.intent == INTENT_OUT)
1956 gfc_error_now ("Variable %qs at %L set to undefined value "
1957 "inside loop beginning at %L as INTENT(OUT) "
1958 "argument to function %qs", do_sym->name,
1959 &a->expr->where, &doloop_list[i]->loc,
1960 expr->symtree->n.sym->name);
1961 else if (f->sym->attr.intent == INTENT_INOUT)
1962 gfc_error_now ("Variable %qs at %L not definable inside loop"
1963 " beginning at %L as INTENT(INOUT) argument to"
1964 " function %qs", do_sym->name,
1965 &a->expr->where, &doloop_list[i]->loc,
1966 expr->symtree->n.sym->name);
1969 a = a->next;
1970 f = f->next;
1973 return 0;
1976 static void
1977 doloop_warn (gfc_namespace *ns)
1979 gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
1982 /* This selction deals with inlining calls to MATMUL. */
1984 /* Auxiliary function to build and simplify an array inquiry function.
1985 dim is zero-based. */
1987 static gfc_expr *
1988 get_array_inq_function (gfc_isym_id id, gfc_expr *e, int dim)
1990 gfc_expr *fcn;
1991 gfc_expr *dim_arg, *kind;
1992 const char *name;
1993 gfc_expr *ec;
1995 switch (id)
1997 case GFC_ISYM_LBOUND:
1998 name = "_gfortran_lbound";
1999 break;
2001 case GFC_ISYM_UBOUND:
2002 name = "_gfortran_ubound";
2003 break;
2005 case GFC_ISYM_SIZE:
2006 name = "_gfortran_size";
2007 break;
2009 default:
2010 gcc_unreachable ();
2013 dim_arg = gfc_get_int_expr (gfc_default_integer_kind, &e->where, dim);
2014 kind = gfc_get_int_expr (gfc_default_integer_kind, &e->where,
2015 gfc_index_integer_kind);
2017 ec = gfc_copy_expr (e);
2018 fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3,
2019 ec, dim_arg, kind);
2020 gfc_simplify_expr (fcn, 0);
2021 return fcn;
2024 /* Builds a logical expression. */
2026 static gfc_expr*
2027 build_logical_expr (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2029 gfc_typespec ts;
2030 gfc_expr *res;
2032 ts.type = BT_LOGICAL;
2033 ts.kind = gfc_default_logical_kind;
2034 res = gfc_get_expr ();
2035 res->where = e1->where;
2036 res->expr_type = EXPR_OP;
2037 res->value.op.op = op;
2038 res->value.op.op1 = e1;
2039 res->value.op.op2 = e2;
2040 res->ts = ts;
2042 return res;
2046 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
2047 compatible typespecs. */
2049 static gfc_expr *
2050 get_operand (gfc_intrinsic_op op, gfc_expr *e1, gfc_expr *e2)
2052 gfc_expr *res;
2054 res = gfc_get_expr ();
2055 res->ts = e1->ts;
2056 res->where = e1->where;
2057 res->expr_type = EXPR_OP;
2058 res->value.op.op = op;
2059 res->value.op.op1 = e1;
2060 res->value.op.op2 = e2;
2061 gfc_simplify_expr (res, 0);
2062 return res;
2065 /* Generate the IF statement for a runtime check if we want to do inlining or
2066 not - putting in the code for both branches and putting it into the syntax
2067 tree is the caller's responsibility. For fixed array sizes, this should be
2068 removed by DCE. Only called for rank-two matrices A and B. */
2070 static gfc_code *
2071 inline_limit_check (gfc_expr *a, gfc_expr *b, enum matrix_case m_case)
2073 gfc_expr *inline_limit;
2074 gfc_code *if_1, *if_2, *else_2;
2075 gfc_expr *b2, *a2, *a1, *m1, *m2;
2076 gfc_typespec ts;
2077 gfc_expr *cond;
2079 gcc_assert (m_case == A2B2);
2081 /* Calculation is done in real to avoid integer overflow. */
2083 inline_limit = gfc_get_constant_expr (BT_REAL, gfc_default_real_kind,
2084 &a->where);
2085 mpfr_set_si (inline_limit->value.real, flag_inline_matmul_limit,
2086 GFC_RND_MODE);
2087 mpfr_pow_ui (inline_limit->value.real, inline_limit->value.real, 3,
2088 GFC_RND_MODE);
2090 a1 = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2091 a2 = get_array_inq_function (GFC_ISYM_SIZE, a, 2);
2092 b2 = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2094 gfc_clear_ts (&ts);
2095 ts.type = BT_REAL;
2096 ts.kind = gfc_default_real_kind;
2097 gfc_convert_type_warn (a1, &ts, 2, 0);
2098 gfc_convert_type_warn (a2, &ts, 2, 0);
2099 gfc_convert_type_warn (b2, &ts, 2, 0);
2101 m1 = get_operand (INTRINSIC_TIMES, a1, a2);
2102 m2 = get_operand (INTRINSIC_TIMES, m1, b2);
2104 cond = build_logical_expr (INTRINSIC_LE, m2, inline_limit);
2105 gfc_simplify_expr (cond, 0);
2107 else_2 = XCNEW (gfc_code);
2108 else_2->op = EXEC_IF;
2109 else_2->loc = a->where;
2111 if_2 = XCNEW (gfc_code);
2112 if_2->op = EXEC_IF;
2113 if_2->expr1 = cond;
2114 if_2->loc = a->where;
2115 if_2->block = else_2;
2117 if_1 = XCNEW (gfc_code);
2118 if_1->op = EXEC_IF;
2119 if_1->block = if_2;
2120 if_1->loc = a->where;
2122 return if_1;
2126 /* Insert code to issue a runtime error if the expressions are not equal. */
2128 static gfc_code *
2129 runtime_error_ne (gfc_expr *e1, gfc_expr *e2, const char *msg)
2131 gfc_expr *cond;
2132 gfc_code *if_1, *if_2;
2133 gfc_code *c;
2134 gfc_actual_arglist *a1, *a2, *a3;
2136 gcc_assert (e1->where.lb);
2137 /* Build the call to runtime_error. */
2138 c = XCNEW (gfc_code);
2139 c->op = EXEC_CALL;
2140 c->loc = e1->where;
2142 /* Get a null-terminated message string. */
2144 a1 = gfc_get_actual_arglist ();
2145 a1->expr = gfc_get_character_expr (gfc_default_character_kind, &e1->where,
2146 msg, strlen(msg)+1);
2147 c->ext.actual = a1;
2149 /* Pass the value of the first expression. */
2150 a2 = gfc_get_actual_arglist ();
2151 a2->expr = gfc_copy_expr (e1);
2152 a1->next = a2;
2154 /* Pass the value of the second expression. */
2155 a3 = gfc_get_actual_arglist ();
2156 a3->expr = gfc_copy_expr (e2);
2157 a2->next = a3;
2159 gfc_check_fe_runtime_error (c->ext.actual);
2160 gfc_resolve_fe_runtime_error (c);
2162 if_2 = XCNEW (gfc_code);
2163 if_2->op = EXEC_IF;
2164 if_2->loc = e1->where;
2165 if_2->next = c;
2167 if_1 = XCNEW (gfc_code);
2168 if_1->op = EXEC_IF;
2169 if_1->block = if_2;
2170 if_1->loc = e1->where;
2172 cond = build_logical_expr (INTRINSIC_NE, e1, e2);
2173 gfc_simplify_expr (cond, 0);
2174 if_2->expr1 = cond;
2176 return if_1;
2179 /* Handle matrix reallocation. Caller is responsible to insert into
2180 the code tree.
2182 For the two-dimensional case, build
2184 if (allocated(c)) then
2185 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
2186 deallocate(c)
2187 allocate (c(size(a,1), size(b,2)))
2188 end if
2189 else
2190 allocate (c(size(a,1),size(b,2)))
2191 end if
2193 and for the other cases correspondingly.
2196 static gfc_code *
2197 matmul_lhs_realloc (gfc_expr *c, gfc_expr *a, gfc_expr *b,
2198 enum matrix_case m_case)
2201 gfc_expr *allocated, *alloc_expr;
2202 gfc_code *if_alloc_1, *if_alloc_2, *if_size_1, *if_size_2;
2203 gfc_code *else_alloc;
2204 gfc_code *deallocate, *allocate1, *allocate_else;
2205 gfc_array_ref *ar;
2206 gfc_expr *cond, *ne1, *ne2;
2208 if (warn_realloc_lhs)
2209 gfc_warning (OPT_Wrealloc_lhs,
2210 "Code for reallocating the allocatable array at %L will "
2211 "be added", &c->where);
2213 alloc_expr = gfc_copy_expr (c);
2215 ar = gfc_find_array_ref (alloc_expr);
2216 gcc_assert (ar && ar->type == AR_FULL);
2218 /* c comes in as a full ref. Change it into a copy and make it into an
2219 element ref so it has the right form for for ALLOCATE. In the same
2220 switch statement, also generate the size comparison for the secod IF
2221 statement. */
2223 ar->type = AR_ELEMENT;
2225 switch (m_case)
2227 case A2B2:
2228 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2229 ar->start[1] = get_array_inq_function (GFC_ISYM_SIZE, b, 2);
2230 ne1 = build_logical_expr (INTRINSIC_NE,
2231 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2232 get_array_inq_function (GFC_ISYM_SIZE, a, 1));
2233 ne2 = build_logical_expr (INTRINSIC_NE,
2234 get_array_inq_function (GFC_ISYM_SIZE, c, 2),
2235 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2236 cond = build_logical_expr (INTRINSIC_OR, ne1, ne2);
2237 break;
2239 case A2B1:
2240 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, a, 1);
2241 cond = build_logical_expr (INTRINSIC_NE,
2242 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2243 get_array_inq_function (GFC_ISYM_SIZE, a, 2));
2244 break;
2246 case A1B2:
2247 ar->start[0] = get_array_inq_function (GFC_ISYM_SIZE, b, 1);
2248 cond = build_logical_expr (INTRINSIC_NE,
2249 get_array_inq_function (GFC_ISYM_SIZE, c, 1),
2250 get_array_inq_function (GFC_ISYM_SIZE, b, 2));
2251 break;
2253 default:
2254 gcc_unreachable();
2258 gfc_simplify_expr (cond, 0);
2260 /* We need two identical allocate statements in two
2261 branches of the IF statement. */
2263 allocate1 = XCNEW (gfc_code);
2264 allocate1->op = EXEC_ALLOCATE;
2265 allocate1->ext.alloc.list = gfc_get_alloc ();
2266 allocate1->loc = c->where;
2267 allocate1->ext.alloc.list->expr = gfc_copy_expr (alloc_expr);
2269 allocate_else = XCNEW (gfc_code);
2270 allocate_else->op = EXEC_ALLOCATE;
2271 allocate_else->ext.alloc.list = gfc_get_alloc ();
2272 allocate_else->loc = c->where;
2273 allocate_else->ext.alloc.list->expr = alloc_expr;
2275 allocated = gfc_build_intrinsic_call (current_ns, GFC_ISYM_ALLOCATED,
2276 "_gfortran_allocated", c->where,
2277 1, gfc_copy_expr (c));
2279 deallocate = XCNEW (gfc_code);
2280 deallocate->op = EXEC_DEALLOCATE;
2281 deallocate->ext.alloc.list = gfc_get_alloc ();
2282 deallocate->ext.alloc.list->expr = gfc_copy_expr (c);
2283 deallocate->next = allocate1;
2284 deallocate->loc = c->where;
2286 if_size_2 = XCNEW (gfc_code);
2287 if_size_2->op = EXEC_IF;
2288 if_size_2->expr1 = cond;
2289 if_size_2->loc = c->where;
2290 if_size_2->next = deallocate;
2292 if_size_1 = XCNEW (gfc_code);
2293 if_size_1->op = EXEC_IF;
2294 if_size_1->block = if_size_2;
2295 if_size_1->loc = c->where;
2297 else_alloc = XCNEW (gfc_code);
2298 else_alloc->op = EXEC_IF;
2299 else_alloc->loc = c->where;
2300 else_alloc->next = allocate_else;
2302 if_alloc_2 = XCNEW (gfc_code);
2303 if_alloc_2->op = EXEC_IF;
2304 if_alloc_2->expr1 = allocated;
2305 if_alloc_2->loc = c->where;
2306 if_alloc_2->next = if_size_1;
2307 if_alloc_2->block = else_alloc;
2309 if_alloc_1 = XCNEW (gfc_code);
2310 if_alloc_1->op = EXEC_IF;
2311 if_alloc_1->block = if_alloc_2;
2312 if_alloc_1->loc = c->where;
2314 return if_alloc_1;
2317 /* Callback function for has_function_or_op. */
2319 static int
2320 is_function_or_op (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
2321 void *data ATTRIBUTE_UNUSED)
2323 if ((*e) == 0)
2324 return 0;
2325 else
2326 return (*e)->expr_type == EXPR_FUNCTION
2327 || (*e)->expr_type == EXPR_OP;
2330 /* Returns true if the expression contains a function. */
2332 static bool
2333 has_function_or_op (gfc_expr **e)
2335 if (e == NULL)
2336 return false;
2337 else
2338 return gfc_expr_walker (e, is_function_or_op, NULL);
2341 /* Freeze (assign to a temporary variable) a single expression. */
2343 static void
2344 freeze_expr (gfc_expr **ep)
2346 gfc_expr *ne;
2347 if (has_function_or_op (ep))
2349 ne = create_var (*ep, "freeze");
2350 *ep = ne;
2354 /* Go through an expression's references and assign them to temporary
2355 variables if they contain functions. This is usually done prior to
2356 front-end scalarization to avoid multiple invocations of functions. */
2358 static void
2359 freeze_references (gfc_expr *e)
2361 gfc_ref *r;
2362 gfc_array_ref *ar;
2363 int i;
2365 for (r=e->ref; r; r=r->next)
2367 if (r->type == REF_SUBSTRING)
2369 if (r->u.ss.start != NULL)
2370 freeze_expr (&r->u.ss.start);
2372 if (r->u.ss.end != NULL)
2373 freeze_expr (&r->u.ss.end);
2375 else if (r->type == REF_ARRAY)
2377 ar = &r->u.ar;
2378 switch (ar->type)
2380 case AR_FULL:
2381 break;
2383 case AR_SECTION:
2384 for (i=0; i<ar->dimen; i++)
2386 if (ar->dimen_type[i] == DIMEN_RANGE)
2388 freeze_expr (&ar->start[i]);
2389 freeze_expr (&ar->end[i]);
2390 freeze_expr (&ar->stride[i]);
2392 else if (ar->dimen_type[i] == DIMEN_ELEMENT)
2394 freeze_expr (&ar->start[i]);
2397 break;
2399 case AR_ELEMENT:
2400 for (i=0; i<ar->dimen; i++)
2401 freeze_expr (&ar->start[i]);
2402 break;
2404 default:
2405 break;
2411 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
2413 static gfc_expr *
2414 convert_to_index_kind (gfc_expr *e)
2416 gfc_expr *res;
2418 gcc_assert (e != NULL);
2420 res = gfc_copy_expr (e);
2422 gcc_assert (e->ts.type == BT_INTEGER);
2424 if (res->ts.kind != gfc_index_integer_kind)
2426 gfc_typespec ts;
2427 gfc_clear_ts (&ts);
2428 ts.type = BT_INTEGER;
2429 ts.kind = gfc_index_integer_kind;
2431 gfc_convert_type_warn (e, &ts, 2, 0);
2434 return res;
2437 /* Function to create a DO loop including creation of the
2438 iteration variable. gfc_expr are copied.*/
2440 static gfc_code *
2441 create_do_loop (gfc_expr *start, gfc_expr *end, gfc_expr *step, locus *where,
2442 gfc_namespace *ns, char *vname)
2445 char name[GFC_MAX_SYMBOL_LEN +1];
2446 gfc_symtree *symtree;
2447 gfc_symbol *symbol;
2448 gfc_expr *i;
2449 gfc_code *n, *n2;
2451 /* Create an expression for the iteration variable. */
2452 if (vname)
2453 sprintf (name, "__var_%d_do_%s", var_num++, vname);
2454 else
2455 sprintf (name, "__var_%d_do", var_num++);
2458 if (gfc_get_sym_tree (name, ns, &symtree, false) != 0)
2459 gcc_unreachable ();
2461 /* Create the loop variable. */
2463 symbol = symtree->n.sym;
2464 symbol->ts.type = BT_INTEGER;
2465 symbol->ts.kind = gfc_index_integer_kind;
2466 symbol->attr.flavor = FL_VARIABLE;
2467 symbol->attr.referenced = 1;
2468 symbol->attr.dimension = 0;
2469 symbol->attr.fe_temp = 1;
2470 gfc_commit_symbol (symbol);
2472 i = gfc_get_expr ();
2473 i->expr_type = EXPR_VARIABLE;
2474 i->ts = symbol->ts;
2475 i->rank = 0;
2476 i->where = *where;
2477 i->symtree = symtree;
2479 /* ... and the nested DO statements. */
2480 n = XCNEW (gfc_code);
2481 n->op = EXEC_DO;
2482 n->loc = *where;
2483 n->ext.iterator = gfc_get_iterator ();
2484 n->ext.iterator->var = i;
2485 n->ext.iterator->start = convert_to_index_kind (start);
2486 n->ext.iterator->end = convert_to_index_kind (end);
2487 if (step)
2488 n->ext.iterator->step = convert_to_index_kind (step);
2489 else
2490 n->ext.iterator->step = gfc_get_int_expr (gfc_index_integer_kind,
2491 where, 1);
2493 n2 = XCNEW (gfc_code);
2494 n2->op = EXEC_DO;
2495 n2->loc = *where;
2496 n2->next = NULL;
2497 n->block = n2;
2498 return n;
2501 /* Get the upper bound of the DO loops for matmul along a dimension. This
2502 is one-based. */
2504 static gfc_expr*
2505 get_size_m1 (gfc_expr *e, int dimen)
2507 mpz_t size;
2508 gfc_expr *res;
2510 if (gfc_array_dimen_size (e, dimen - 1, &size))
2512 res = gfc_get_constant_expr (BT_INTEGER,
2513 gfc_index_integer_kind, &e->where);
2514 mpz_sub_ui (res->value.integer, size, 1);
2515 mpz_clear (size);
2517 else
2519 res = get_operand (INTRINSIC_MINUS,
2520 get_array_inq_function (GFC_ISYM_SIZE, e, dimen),
2521 gfc_get_int_expr (gfc_index_integer_kind,
2522 &e->where, 1));
2523 gfc_simplify_expr (res, 0);
2526 return res;
2529 /* Function to return a scalarized expression. It is assumed that indices are
2530 zero based to make generation of DO loops easier. A zero as index will
2531 access the first element along a dimension. Single element references will
2532 be skipped. A NULL as an expression will be replaced by a full reference.
2533 This assumes that the index loops have gfc_index_integer_kind, and that all
2534 references have been frozen. */
2536 static gfc_expr*
2537 scalarized_expr (gfc_expr *e_in, gfc_expr **index, int count_index)
2539 gfc_array_ref *ar;
2540 int i;
2541 int rank;
2542 gfc_expr *e;
2543 int i_index;
2544 bool was_fullref;
2546 e = gfc_copy_expr(e_in);
2548 rank = e->rank;
2550 ar = gfc_find_array_ref (e);
2552 /* We scalarize count_index variables, reducing the rank by count_index. */
2554 e->rank = rank - count_index;
2556 was_fullref = ar->type == AR_FULL;
2558 if (e->rank == 0)
2559 ar->type = AR_ELEMENT;
2560 else
2561 ar->type = AR_SECTION;
2563 /* Loop over the indices. For each index, create the expression
2564 index * stride + lbound(e, dim). */
2566 i_index = 0;
2567 for (i=0; i < ar->dimen; i++)
2569 if (was_fullref || ar->dimen_type[i] == DIMEN_RANGE)
2571 if (index[i_index] != NULL)
2573 gfc_expr *lbound, *nindex;
2574 gfc_expr *loopvar;
2576 loopvar = gfc_copy_expr (index[i_index]);
2578 if (ar->stride[i])
2580 gfc_expr *tmp;
2582 tmp = gfc_copy_expr(ar->stride[i]);
2583 if (tmp->ts.kind != gfc_index_integer_kind)
2585 gfc_typespec ts;
2586 gfc_clear_ts (&ts);
2587 ts.type = BT_INTEGER;
2588 ts.kind = gfc_index_integer_kind;
2589 gfc_convert_type (tmp, &ts, 2);
2591 nindex = get_operand (INTRINSIC_TIMES, loopvar, tmp);
2593 else
2594 nindex = loopvar;
2596 /* Calculate the lower bound of the expression. */
2597 if (ar->start[i])
2599 lbound = gfc_copy_expr (ar->start[i]);
2600 if (lbound->ts.kind != gfc_index_integer_kind)
2602 gfc_typespec ts;
2603 gfc_clear_ts (&ts);
2604 ts.type = BT_INTEGER;
2605 ts.kind = gfc_index_integer_kind;
2606 gfc_convert_type (lbound, &ts, 2);
2610 else
2612 gfc_expr *lbound_e;
2613 gfc_ref *ref;
2615 lbound_e = gfc_copy_expr (e_in);
2617 for (ref = lbound_e->ref; ref; ref = ref->next)
2618 if (ref->type == REF_ARRAY
2619 && (ref->u.ar.type == AR_FULL
2620 || ref->u.ar.type == AR_SECTION))
2621 break;
2623 if (ref->next)
2625 gfc_free_ref_list (ref->next);
2626 ref->next = NULL;
2629 if (!was_fullref)
2631 /* Look at full individual sections, like a(:). The first index
2632 is the lbound of a full ref. */
2633 int j;
2634 gfc_array_ref *ar;
2636 ar = &ref->u.ar;
2637 ar->type = AR_FULL;
2638 for (j = 0; j < ar->dimen; j++)
2640 gfc_free_expr (ar->start[j]);
2641 ar->start[j] = NULL;
2642 gfc_free_expr (ar->end[j]);
2643 ar->end[j] = NULL;
2644 gfc_free_expr (ar->stride[j]);
2645 ar->stride[j] = NULL;
2648 /* We have to get rid of the shape, if there is one. Do
2649 so by freeing it and calling gfc_resolve to rebuild
2650 it, if necessary. */
2652 if (lbound_e->shape)
2653 gfc_free_shape (&(lbound_e->shape), lbound_e->rank);
2655 lbound_e->rank = ar->dimen;
2656 gfc_resolve_expr (lbound_e);
2658 lbound = get_array_inq_function (GFC_ISYM_LBOUND, lbound_e,
2659 i + 1);
2660 gfc_free_expr (lbound_e);
2663 ar->dimen_type[i] = DIMEN_ELEMENT;
2665 gfc_free_expr (ar->start[i]);
2666 ar->start[i] = get_operand (INTRINSIC_PLUS, nindex, lbound);
2668 gfc_free_expr (ar->end[i]);
2669 ar->end[i] = NULL;
2670 gfc_free_expr (ar->stride[i]);
2671 ar->stride[i] = NULL;
2672 gfc_simplify_expr (ar->start[i], 0);
2674 else if (was_fullref)
2676 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
2678 i_index ++;
2682 return e;
2685 /* Helper function to check for a dimen vector as subscript. */
2687 static bool
2688 has_dimen_vector_ref (gfc_expr *e)
2690 gfc_array_ref *ar;
2691 int i;
2693 ar = gfc_find_array_ref (e);
2694 gcc_assert (ar);
2695 if (ar->type == AR_FULL)
2696 return false;
2698 for (i=0; i<ar->dimen; i++)
2699 if (ar->dimen_type[i] == DIMEN_VECTOR)
2700 return true;
2702 return false;
2705 /* If handed an expression of the form
2707 CONJG(A)
2709 check if A can be handled by matmul and return if there is an uneven number
2710 of CONJG calls. Return a pointer to the array when everything is OK, NULL
2711 otherwise. The caller has to check for the correct rank. */
2713 static gfc_expr*
2714 check_conjg_variable (gfc_expr *e, bool *conjg)
2716 *conjg = false;
2720 if (e->expr_type == EXPR_VARIABLE)
2722 gcc_assert (e->rank == 1 || e->rank == 2);
2723 return e;
2725 else if (e->expr_type == EXPR_FUNCTION)
2727 if (e->value.function.isym == NULL)
2728 return NULL;
2730 if (e->value.function.isym->id == GFC_ISYM_CONJG)
2731 *conjg = !*conjg;
2732 else return NULL;
2734 else
2735 return NULL;
2737 e = e->value.function.actual->expr;
2739 while(1);
2741 return NULL;
2744 /* Inline assignments of the form c = matmul(a,b).
2745 Handle only the cases currently where b and c are rank-two arrays.
2747 This basically translates the code to
2749 BLOCK
2750 integer i,j,k
2751 c = 0
2752 do j=0, size(b,2)-1
2753 do k=0, size(a, 2)-1
2754 do i=0, size(a, 1)-1
2755 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
2756 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
2757 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
2758 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
2759 end do
2760 end do
2761 end do
2762 END BLOCK
2766 static int
2767 inline_matmul_assign (gfc_code **c, int *walk_subtrees,
2768 void *data ATTRIBUTE_UNUSED)
2770 gfc_code *co = *c;
2771 gfc_expr *expr1, *expr2;
2772 gfc_expr *matrix_a, *matrix_b;
2773 gfc_actual_arglist *a, *b;
2774 gfc_code *do_1, *do_2, *do_3, *assign_zero, *assign_matmul;
2775 gfc_expr *zero_e;
2776 gfc_expr *u1, *u2, *u3;
2777 gfc_expr *list[2];
2778 gfc_expr *ascalar, *bscalar, *cscalar;
2779 gfc_expr *mult;
2780 gfc_expr *var_1, *var_2, *var_3;
2781 gfc_expr *zero;
2782 gfc_namespace *ns;
2783 gfc_intrinsic_op op_times, op_plus;
2784 enum matrix_case m_case;
2785 int i;
2786 gfc_code *if_limit = NULL;
2787 gfc_code **next_code_point;
2788 bool conjg_a, conjg_b;
2790 if (co->op != EXEC_ASSIGN)
2791 return 0;
2793 expr1 = co->expr1;
2794 expr2 = co->expr2;
2795 if (expr2->expr_type != EXPR_FUNCTION
2796 || expr2->value.function.isym == NULL
2797 || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
2798 return 0;
2800 current_code = c;
2801 inserted_block = NULL;
2802 changed_statement = NULL;
2804 a = expr2->value.function.actual;
2805 matrix_a = check_conjg_variable (a->expr, &conjg_a);
2806 if (matrix_a == NULL)
2807 return 0;
2809 b = a->next;
2810 matrix_b = check_conjg_variable (b->expr, &conjg_b);
2811 if (matrix_b == NULL)
2812 return 0;
2814 if (has_dimen_vector_ref (expr1) || has_dimen_vector_ref (matrix_a)
2815 || has_dimen_vector_ref (matrix_b))
2816 return 0;
2818 /* We do not handle data dependencies yet. */
2819 if (gfc_check_dependency (expr1, matrix_a, true)
2820 || gfc_check_dependency (expr1, matrix_b, true))
2821 return 0;
2823 if (matrix_a->rank == 2)
2824 m_case = matrix_b->rank == 1 ? A2B1 : A2B2;
2825 else
2826 m_case = A1B2;
2829 ns = insert_block ();
2831 /* Assign the type of the zero expression for initializing the resulting
2832 array, and the expression (+ and * for real, integer and complex;
2833 .and. and .or for logical. */
2835 switch(expr1->ts.type)
2837 case BT_INTEGER:
2838 zero_e = gfc_get_int_expr (expr1->ts.kind, &expr1->where, 0);
2839 op_times = INTRINSIC_TIMES;
2840 op_plus = INTRINSIC_PLUS;
2841 break;
2843 case BT_LOGICAL:
2844 op_times = INTRINSIC_AND;
2845 op_plus = INTRINSIC_OR;
2846 zero_e = gfc_get_logical_expr (expr1->ts.kind, &expr1->where,
2848 break;
2849 case BT_REAL:
2850 zero_e = gfc_get_constant_expr (BT_REAL, expr1->ts.kind,
2851 &expr1->where);
2852 mpfr_set_si (zero_e->value.real, 0, GFC_RND_MODE);
2853 op_times = INTRINSIC_TIMES;
2854 op_plus = INTRINSIC_PLUS;
2855 break;
2857 case BT_COMPLEX:
2858 zero_e = gfc_get_constant_expr (BT_COMPLEX, expr1->ts.kind,
2859 &expr1->where);
2860 mpc_set_si_si (zero_e->value.complex, 0, 0, GFC_RND_MODE);
2861 op_times = INTRINSIC_TIMES;
2862 op_plus = INTRINSIC_PLUS;
2864 break;
2866 default:
2867 gcc_unreachable();
2870 current_code = &ns->code;
2872 /* Freeze the references, keeping track of how many temporary variables were
2873 created. */
2874 n_vars = 0;
2875 freeze_references (matrix_a);
2876 freeze_references (matrix_b);
2877 freeze_references (expr1);
2879 if (n_vars == 0)
2880 next_code_point = current_code;
2881 else
2883 next_code_point = &ns->code;
2884 for (i=0; i<n_vars; i++)
2885 next_code_point = &(*next_code_point)->next;
2888 /* Take care of the inline flag. If the limit check evaluates to a
2889 constant, dead code elimination will eliminate the unneeded branch. */
2891 if (m_case == A2B2 && flag_inline_matmul_limit > 0)
2893 if_limit = inline_limit_check (matrix_a, matrix_b, m_case);
2895 /* Insert the original statement into the else branch. */
2896 if_limit->block->block->next = co;
2897 co->next = NULL;
2899 /* ... and the new ones go into the original one. */
2900 *next_code_point = if_limit;
2901 next_code_point = &if_limit->block->next;
2904 assign_zero = XCNEW (gfc_code);
2905 assign_zero->op = EXEC_ASSIGN;
2906 assign_zero->loc = co->loc;
2907 assign_zero->expr1 = gfc_copy_expr (expr1);
2908 assign_zero->expr2 = zero_e;
2910 /* Handle the reallocation, if needed. */
2911 if (flag_realloc_lhs && gfc_is_reallocatable_lhs (expr1))
2913 gfc_code *lhs_alloc;
2915 /* Only need to check a single dimension for the A2B2 case for
2916 bounds checking, the rest will be allocated. */
2918 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS && m_case == A2B2)
2920 gfc_code *test;
2921 gfc_expr *a2, *b1;
2923 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
2924 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
2925 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
2926 "in MATMUL intrinsic: Is %ld, should be %ld");
2927 *next_code_point = test;
2928 next_code_point = &test->next;
2932 lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case);
2934 *next_code_point = lhs_alloc;
2935 next_code_point = &lhs_alloc->next;
2938 else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
2940 gfc_code *test;
2941 gfc_expr *a2, *b1, *c1, *c2, *a1, *b2;
2943 if (m_case == A2B2 || m_case == A2B1)
2945 a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2);
2946 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
2947 test = runtime_error_ne (b1, a2, "Dimension of array B incorrect "
2948 "in MATMUL intrinsic: Is %ld, should be %ld");
2949 *next_code_point = test;
2950 next_code_point = &test->next;
2952 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
2953 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
2955 if (m_case == A2B2)
2956 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
2957 "MATMUL intrinsic for dimension 1: "
2958 "is %ld, should be %ld");
2959 else if (m_case == A2B1)
2960 test = runtime_error_ne (c1, a1, "Incorrect extent in return array in "
2961 "MATMUL intrinsic: "
2962 "is %ld, should be %ld");
2965 *next_code_point = test;
2966 next_code_point = &test->next;
2968 else if (m_case == A1B2)
2970 a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1);
2971 b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1);
2972 test = runtime_error_ne (b1, a1, "Dimension of array B incorrect "
2973 "in MATMUL intrinsic: Is %ld, should be %ld");
2974 *next_code_point = test;
2975 next_code_point = &test->next;
2977 c1 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 1);
2978 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
2980 test = runtime_error_ne (c1, b2, "Incorrect extent in return array in "
2981 "MATMUL intrinsic: "
2982 "is %ld, should be %ld");
2984 *next_code_point = test;
2985 next_code_point = &test->next;
2988 if (m_case == A2B2)
2990 c2 = get_array_inq_function (GFC_ISYM_SIZE, expr1, 2);
2991 b2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 2);
2992 test = runtime_error_ne (c2, b2, "Incorrect extent in return array in "
2993 "MATMUL intrinsic for dimension 2: is %ld, should be %ld");
2995 *next_code_point = test;
2996 next_code_point = &test->next;
3000 *next_code_point = assign_zero;
3002 zero = gfc_get_int_expr (gfc_index_integer_kind, &co->loc, 0);
3004 assign_matmul = XCNEW (gfc_code);
3005 assign_matmul->op = EXEC_ASSIGN;
3006 assign_matmul->loc = co->loc;
3008 /* Get the bounds for the loops, create them and create the scalarized
3009 expressions. */
3011 switch (m_case)
3013 case A2B2:
3014 inline_limit_check (matrix_a, matrix_b, m_case);
3016 u1 = get_size_m1 (matrix_b, 2);
3017 u2 = get_size_m1 (matrix_a, 2);
3018 u3 = get_size_m1 (matrix_a, 1);
3020 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3021 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3022 do_3 = create_do_loop (gfc_copy_expr (zero), u3, NULL, &co->loc, ns);
3024 do_1->block->next = do_2;
3025 do_2->block->next = do_3;
3026 do_3->block->next = assign_matmul;
3028 var_1 = do_1->ext.iterator->var;
3029 var_2 = do_2->ext.iterator->var;
3030 var_3 = do_3->ext.iterator->var;
3032 list[0] = var_3;
3033 list[1] = var_1;
3034 cscalar = scalarized_expr (co->expr1, list, 2);
3036 list[0] = var_3;
3037 list[1] = var_2;
3038 ascalar = scalarized_expr (matrix_a, list, 2);
3040 list[0] = var_2;
3041 list[1] = var_1;
3042 bscalar = scalarized_expr (matrix_b, list, 2);
3044 break;
3046 case A2B1:
3047 u1 = get_size_m1 (matrix_b, 1);
3048 u2 = get_size_m1 (matrix_a, 1);
3050 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3051 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3053 do_1->block->next = do_2;
3054 do_2->block->next = assign_matmul;
3056 var_1 = do_1->ext.iterator->var;
3057 var_2 = do_2->ext.iterator->var;
3059 list[0] = var_2;
3060 cscalar = scalarized_expr (co->expr1, list, 1);
3062 list[0] = var_2;
3063 list[1] = var_1;
3064 ascalar = scalarized_expr (matrix_a, list, 2);
3066 list[0] = var_1;
3067 bscalar = scalarized_expr (matrix_b, list, 1);
3069 break;
3071 case A1B2:
3072 u1 = get_size_m1 (matrix_b, 2);
3073 u2 = get_size_m1 (matrix_a, 1);
3075 do_1 = create_do_loop (gfc_copy_expr (zero), u1, NULL, &co->loc, ns);
3076 do_2 = create_do_loop (gfc_copy_expr (zero), u2, NULL, &co->loc, ns);
3078 do_1->block->next = do_2;
3079 do_2->block->next = assign_matmul;
3081 var_1 = do_1->ext.iterator->var;
3082 var_2 = do_2->ext.iterator->var;
3084 list[0] = var_1;
3085 cscalar = scalarized_expr (co->expr1, list, 1);
3087 list[0] = var_2;
3088 ascalar = scalarized_expr (matrix_a, list, 1);
3090 list[0] = var_2;
3091 list[1] = var_1;
3092 bscalar = scalarized_expr (matrix_b, list, 2);
3094 break;
3096 default:
3097 gcc_unreachable();
3100 if (conjg_a)
3101 ascalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
3102 matrix_a->where, 1, ascalar);
3104 if (conjg_b)
3105 bscalar = gfc_build_intrinsic_call (ns, GFC_ISYM_CONJG, "conjg",
3106 matrix_b->where, 1, bscalar);
3108 /* First loop comes after the zero assignment. */
3109 assign_zero->next = do_1;
3111 /* Build the assignment expression in the loop. */
3112 assign_matmul->expr1 = gfc_copy_expr (cscalar);
3114 mult = get_operand (op_times, ascalar, bscalar);
3115 assign_matmul->expr2 = get_operand (op_plus, cscalar, mult);
3117 /* If we don't want to keep the original statement around in
3118 the else branch, we can free it. */
3120 if (if_limit == NULL)
3121 gfc_free_statements(co);
3122 else
3123 co->next = NULL;
3125 gfc_free_expr (zero);
3126 *walk_subtrees = 0;
3127 return 0;
3130 #define WALK_SUBEXPR(NODE) \
3131 do \
3133 result = gfc_expr_walker (&(NODE), exprfn, data); \
3134 if (result) \
3135 return result; \
3137 while (0)
3138 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
3140 /* Walk expression *E, calling EXPRFN on each expression in it. */
3143 gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
3145 while (*e)
3147 int walk_subtrees = 1;
3148 gfc_actual_arglist *a;
3149 gfc_ref *r;
3150 gfc_constructor *c;
3152 int result = exprfn (e, &walk_subtrees, data);
3153 if (result)
3154 return result;
3155 if (walk_subtrees)
3156 switch ((*e)->expr_type)
3158 case EXPR_OP:
3159 WALK_SUBEXPR ((*e)->value.op.op1);
3160 WALK_SUBEXPR_TAIL ((*e)->value.op.op2);
3161 break;
3162 case EXPR_FUNCTION:
3163 for (a = (*e)->value.function.actual; a; a = a->next)
3164 WALK_SUBEXPR (a->expr);
3165 break;
3166 case EXPR_COMPCALL:
3167 case EXPR_PPC:
3168 WALK_SUBEXPR ((*e)->value.compcall.base_object);
3169 for (a = (*e)->value.compcall.actual; a; a = a->next)
3170 WALK_SUBEXPR (a->expr);
3171 break;
3173 case EXPR_STRUCTURE:
3174 case EXPR_ARRAY:
3175 for (c = gfc_constructor_first ((*e)->value.constructor); c;
3176 c = gfc_constructor_next (c))
3178 if (c->iterator == NULL)
3179 WALK_SUBEXPR (c->expr);
3180 else
3182 iterator_level ++;
3183 WALK_SUBEXPR (c->expr);
3184 iterator_level --;
3185 WALK_SUBEXPR (c->iterator->var);
3186 WALK_SUBEXPR (c->iterator->start);
3187 WALK_SUBEXPR (c->iterator->end);
3188 WALK_SUBEXPR (c->iterator->step);
3192 if ((*e)->expr_type != EXPR_ARRAY)
3193 break;
3195 /* Fall through to the variable case in order to walk the
3196 reference. */
3198 case EXPR_SUBSTRING:
3199 case EXPR_VARIABLE:
3200 for (r = (*e)->ref; r; r = r->next)
3202 gfc_array_ref *ar;
3203 int i;
3205 switch (r->type)
3207 case REF_ARRAY:
3208 ar = &r->u.ar;
3209 if (ar->type == AR_SECTION || ar->type == AR_ELEMENT)
3211 for (i=0; i< ar->dimen; i++)
3213 WALK_SUBEXPR (ar->start[i]);
3214 WALK_SUBEXPR (ar->end[i]);
3215 WALK_SUBEXPR (ar->stride[i]);
3219 break;
3221 case REF_SUBSTRING:
3222 WALK_SUBEXPR (r->u.ss.start);
3223 WALK_SUBEXPR (r->u.ss.end);
3224 break;
3226 case REF_COMPONENT:
3227 break;
3231 default:
3232 break;
3234 return 0;
3236 return 0;
3239 #define WALK_SUBCODE(NODE) \
3240 do \
3242 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
3243 if (result) \
3244 return result; \
3246 while (0)
3248 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
3249 on each expression in it. If any of the hooks returns non-zero, that
3250 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
3251 no subcodes or subexpressions are traversed. */
3254 gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
3255 void *data)
3257 for (; *c; c = &(*c)->next)
3259 int walk_subtrees = 1;
3260 int result = codefn (c, &walk_subtrees, data);
3261 if (result)
3262 return result;
3264 if (walk_subtrees)
3266 gfc_code *b;
3267 gfc_actual_arglist *a;
3268 gfc_code *co;
3269 gfc_association_list *alist;
3270 bool saved_in_omp_workshare;
3272 /* There might be statement insertions before the current code,
3273 which must not affect the expression walker. */
3275 co = *c;
3276 saved_in_omp_workshare = in_omp_workshare;
3278 switch (co->op)
3281 case EXEC_BLOCK:
3282 WALK_SUBCODE (co->ext.block.ns->code);
3283 if (co->ext.block.assoc)
3285 bool saved_in_assoc_list = in_assoc_list;
3287 in_assoc_list = true;
3288 for (alist = co->ext.block.assoc; alist; alist = alist->next)
3289 WALK_SUBEXPR (alist->target);
3291 in_assoc_list = saved_in_assoc_list;
3294 break;
3296 case EXEC_DO:
3297 doloop_level ++;
3298 WALK_SUBEXPR (co->ext.iterator->var);
3299 WALK_SUBEXPR (co->ext.iterator->start);
3300 WALK_SUBEXPR (co->ext.iterator->end);
3301 WALK_SUBEXPR (co->ext.iterator->step);
3302 break;
3304 case EXEC_CALL:
3305 case EXEC_ASSIGN_CALL:
3306 for (a = co->ext.actual; a; a = a->next)
3307 WALK_SUBEXPR (a->expr);
3308 break;
3310 case EXEC_CALL_PPC:
3311 WALK_SUBEXPR (co->expr1);
3312 for (a = co->ext.actual; a; a = a->next)
3313 WALK_SUBEXPR (a->expr);
3314 break;
3316 case EXEC_SELECT:
3317 WALK_SUBEXPR (co->expr1);
3318 for (b = co->block; b; b = b->block)
3320 gfc_case *cp;
3321 for (cp = b->ext.block.case_list; cp; cp = cp->next)
3323 WALK_SUBEXPR (cp->low);
3324 WALK_SUBEXPR (cp->high);
3326 WALK_SUBCODE (b->next);
3328 continue;
3330 case EXEC_ALLOCATE:
3331 case EXEC_DEALLOCATE:
3333 gfc_alloc *a;
3334 for (a = co->ext.alloc.list; a; a = a->next)
3335 WALK_SUBEXPR (a->expr);
3336 break;
3339 case EXEC_FORALL:
3340 case EXEC_DO_CONCURRENT:
3342 gfc_forall_iterator *fa;
3343 for (fa = co->ext.forall_iterator; fa; fa = fa->next)
3345 WALK_SUBEXPR (fa->var);
3346 WALK_SUBEXPR (fa->start);
3347 WALK_SUBEXPR (fa->end);
3348 WALK_SUBEXPR (fa->stride);
3350 if (co->op == EXEC_FORALL)
3351 forall_level ++;
3352 break;
3355 case EXEC_OPEN:
3356 WALK_SUBEXPR (co->ext.open->unit);
3357 WALK_SUBEXPR (co->ext.open->file);
3358 WALK_SUBEXPR (co->ext.open->status);
3359 WALK_SUBEXPR (co->ext.open->access);
3360 WALK_SUBEXPR (co->ext.open->form);
3361 WALK_SUBEXPR (co->ext.open->recl);
3362 WALK_SUBEXPR (co->ext.open->blank);
3363 WALK_SUBEXPR (co->ext.open->position);
3364 WALK_SUBEXPR (co->ext.open->action);
3365 WALK_SUBEXPR (co->ext.open->delim);
3366 WALK_SUBEXPR (co->ext.open->pad);
3367 WALK_SUBEXPR (co->ext.open->iostat);
3368 WALK_SUBEXPR (co->ext.open->iomsg);
3369 WALK_SUBEXPR (co->ext.open->convert);
3370 WALK_SUBEXPR (co->ext.open->decimal);
3371 WALK_SUBEXPR (co->ext.open->encoding);
3372 WALK_SUBEXPR (co->ext.open->round);
3373 WALK_SUBEXPR (co->ext.open->sign);
3374 WALK_SUBEXPR (co->ext.open->asynchronous);
3375 WALK_SUBEXPR (co->ext.open->id);
3376 WALK_SUBEXPR (co->ext.open->newunit);
3377 break;
3379 case EXEC_CLOSE:
3380 WALK_SUBEXPR (co->ext.close->unit);
3381 WALK_SUBEXPR (co->ext.close->status);
3382 WALK_SUBEXPR (co->ext.close->iostat);
3383 WALK_SUBEXPR (co->ext.close->iomsg);
3384 break;
3386 case EXEC_BACKSPACE:
3387 case EXEC_ENDFILE:
3388 case EXEC_REWIND:
3389 case EXEC_FLUSH:
3390 WALK_SUBEXPR (co->ext.filepos->unit);
3391 WALK_SUBEXPR (co->ext.filepos->iostat);
3392 WALK_SUBEXPR (co->ext.filepos->iomsg);
3393 break;
3395 case EXEC_INQUIRE:
3396 WALK_SUBEXPR (co->ext.inquire->unit);
3397 WALK_SUBEXPR (co->ext.inquire->file);
3398 WALK_SUBEXPR (co->ext.inquire->iomsg);
3399 WALK_SUBEXPR (co->ext.inquire->iostat);
3400 WALK_SUBEXPR (co->ext.inquire->exist);
3401 WALK_SUBEXPR (co->ext.inquire->opened);
3402 WALK_SUBEXPR (co->ext.inquire->number);
3403 WALK_SUBEXPR (co->ext.inquire->named);
3404 WALK_SUBEXPR (co->ext.inquire->name);
3405 WALK_SUBEXPR (co->ext.inquire->access);
3406 WALK_SUBEXPR (co->ext.inquire->sequential);
3407 WALK_SUBEXPR (co->ext.inquire->direct);
3408 WALK_SUBEXPR (co->ext.inquire->form);
3409 WALK_SUBEXPR (co->ext.inquire->formatted);
3410 WALK_SUBEXPR (co->ext.inquire->unformatted);
3411 WALK_SUBEXPR (co->ext.inquire->recl);
3412 WALK_SUBEXPR (co->ext.inquire->nextrec);
3413 WALK_SUBEXPR (co->ext.inquire->blank);
3414 WALK_SUBEXPR (co->ext.inquire->position);
3415 WALK_SUBEXPR (co->ext.inquire->action);
3416 WALK_SUBEXPR (co->ext.inquire->read);
3417 WALK_SUBEXPR (co->ext.inquire->write);
3418 WALK_SUBEXPR (co->ext.inquire->readwrite);
3419 WALK_SUBEXPR (co->ext.inquire->delim);
3420 WALK_SUBEXPR (co->ext.inquire->encoding);
3421 WALK_SUBEXPR (co->ext.inquire->pad);
3422 WALK_SUBEXPR (co->ext.inquire->iolength);
3423 WALK_SUBEXPR (co->ext.inquire->convert);
3424 WALK_SUBEXPR (co->ext.inquire->strm_pos);
3425 WALK_SUBEXPR (co->ext.inquire->asynchronous);
3426 WALK_SUBEXPR (co->ext.inquire->decimal);
3427 WALK_SUBEXPR (co->ext.inquire->pending);
3428 WALK_SUBEXPR (co->ext.inquire->id);
3429 WALK_SUBEXPR (co->ext.inquire->sign);
3430 WALK_SUBEXPR (co->ext.inquire->size);
3431 WALK_SUBEXPR (co->ext.inquire->round);
3432 break;
3434 case EXEC_WAIT:
3435 WALK_SUBEXPR (co->ext.wait->unit);
3436 WALK_SUBEXPR (co->ext.wait->iostat);
3437 WALK_SUBEXPR (co->ext.wait->iomsg);
3438 WALK_SUBEXPR (co->ext.wait->id);
3439 break;
3441 case EXEC_READ:
3442 case EXEC_WRITE:
3443 WALK_SUBEXPR (co->ext.dt->io_unit);
3444 WALK_SUBEXPR (co->ext.dt->format_expr);
3445 WALK_SUBEXPR (co->ext.dt->rec);
3446 WALK_SUBEXPR (co->ext.dt->advance);
3447 WALK_SUBEXPR (co->ext.dt->iostat);
3448 WALK_SUBEXPR (co->ext.dt->size);
3449 WALK_SUBEXPR (co->ext.dt->iomsg);
3450 WALK_SUBEXPR (co->ext.dt->id);
3451 WALK_SUBEXPR (co->ext.dt->pos);
3452 WALK_SUBEXPR (co->ext.dt->asynchronous);
3453 WALK_SUBEXPR (co->ext.dt->blank);
3454 WALK_SUBEXPR (co->ext.dt->decimal);
3455 WALK_SUBEXPR (co->ext.dt->delim);
3456 WALK_SUBEXPR (co->ext.dt->pad);
3457 WALK_SUBEXPR (co->ext.dt->round);
3458 WALK_SUBEXPR (co->ext.dt->sign);
3459 WALK_SUBEXPR (co->ext.dt->extra_comma);
3460 break;
3462 case EXEC_OMP_PARALLEL:
3463 case EXEC_OMP_PARALLEL_DO:
3464 case EXEC_OMP_PARALLEL_DO_SIMD:
3465 case EXEC_OMP_PARALLEL_SECTIONS:
3467 in_omp_workshare = false;
3469 /* This goto serves as a shortcut to avoid code
3470 duplication or a larger if or switch statement. */
3471 goto check_omp_clauses;
3473 case EXEC_OMP_WORKSHARE:
3474 case EXEC_OMP_PARALLEL_WORKSHARE:
3476 in_omp_workshare = true;
3478 /* Fall through */
3480 case EXEC_OMP_DISTRIBUTE:
3481 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO:
3482 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD:
3483 case EXEC_OMP_DISTRIBUTE_SIMD:
3484 case EXEC_OMP_DO:
3485 case EXEC_OMP_DO_SIMD:
3486 case EXEC_OMP_SECTIONS:
3487 case EXEC_OMP_SINGLE:
3488 case EXEC_OMP_END_SINGLE:
3489 case EXEC_OMP_SIMD:
3490 case EXEC_OMP_TARGET:
3491 case EXEC_OMP_TARGET_DATA:
3492 case EXEC_OMP_TARGET_TEAMS:
3493 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE:
3494 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO:
3495 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
3496 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD:
3497 case EXEC_OMP_TARGET_UPDATE:
3498 case EXEC_OMP_TASK:
3499 case EXEC_OMP_TEAMS:
3500 case EXEC_OMP_TEAMS_DISTRIBUTE:
3501 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO:
3502 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD:
3503 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD:
3505 /* Come to this label only from the
3506 EXEC_OMP_PARALLEL_* cases above. */
3508 check_omp_clauses:
3510 if (co->ext.omp_clauses)
3512 gfc_omp_namelist *n;
3513 static int list_types[]
3514 = { OMP_LIST_ALIGNED, OMP_LIST_LINEAR, OMP_LIST_DEPEND,
3515 OMP_LIST_MAP, OMP_LIST_TO, OMP_LIST_FROM };
3516 size_t idx;
3517 WALK_SUBEXPR (co->ext.omp_clauses->if_expr);
3518 WALK_SUBEXPR (co->ext.omp_clauses->final_expr);
3519 WALK_SUBEXPR (co->ext.omp_clauses->num_threads);
3520 WALK_SUBEXPR (co->ext.omp_clauses->chunk_size);
3521 WALK_SUBEXPR (co->ext.omp_clauses->safelen_expr);
3522 WALK_SUBEXPR (co->ext.omp_clauses->simdlen_expr);
3523 WALK_SUBEXPR (co->ext.omp_clauses->num_teams);
3524 WALK_SUBEXPR (co->ext.omp_clauses->device);
3525 WALK_SUBEXPR (co->ext.omp_clauses->thread_limit);
3526 WALK_SUBEXPR (co->ext.omp_clauses->dist_chunk_size);
3527 for (idx = 0;
3528 idx < sizeof (list_types) / sizeof (list_types[0]);
3529 idx++)
3530 for (n = co->ext.omp_clauses->lists[list_types[idx]];
3531 n; n = n->next)
3532 WALK_SUBEXPR (n->expr);
3534 break;
3535 default:
3536 break;
3539 WALK_SUBEXPR (co->expr1);
3540 WALK_SUBEXPR (co->expr2);
3541 WALK_SUBEXPR (co->expr3);
3542 WALK_SUBEXPR (co->expr4);
3543 for (b = co->block; b; b = b->block)
3545 WALK_SUBEXPR (b->expr1);
3546 WALK_SUBEXPR (b->expr2);
3547 WALK_SUBCODE (b->next);
3550 if (co->op == EXEC_FORALL)
3551 forall_level --;
3553 if (co->op == EXEC_DO)
3554 doloop_level --;
3556 in_omp_workshare = saved_in_omp_workshare;
3559 return 0;