1 /* Pass manager for Fortran front end.
2 Copyright (C) 2010-2018 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
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
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/>. */
23 #include "coretypes.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 int do_intent (gfc_expr
**);
43 static int do_subscript (gfc_expr
**);
44 static void optimize_reduction (gfc_namespace
*);
45 static int callback_reduction (gfc_expr
**, int *, void *);
46 static void realloc_strings (gfc_namespace
*);
47 static gfc_expr
*create_var (gfc_expr
*, const char *vname
=NULL
);
48 static int matmul_to_var_expr (gfc_expr
**, int *, void *);
49 static int matmul_to_var_code (gfc_code
**, int *, void *);
50 static int inline_matmul_assign (gfc_code
**, int *, void *);
51 static gfc_code
* create_do_loop (gfc_expr
*, gfc_expr
*, gfc_expr
*,
52 locus
*, gfc_namespace
*,
54 static gfc_expr
* check_conjg_transpose_variable (gfc_expr
*, bool *,
56 static bool has_dimen_vector_ref (gfc_expr
*);
57 static int matmul_temp_args (gfc_code
**, int *,void *data
);
58 static int index_interchange (gfc_code
**, int*, void *);
61 static void check_locus (gfc_namespace
*);
64 /* How deep we are inside an argument list. */
66 static int count_arglist
;
68 /* Vector of gfc_expr ** we operate on. */
70 static vec
<gfc_expr
**> expr_array
;
72 /* Pointer to the gfc_code we currently work on - to be able to insert
73 a block before the statement. */
75 static gfc_code
**current_code
;
77 /* Pointer to the block to be inserted, and the statement we are
78 changing within the block. */
80 static gfc_code
*inserted_block
, **changed_statement
;
82 /* The namespace we are currently dealing with. */
84 static gfc_namespace
*current_ns
;
86 /* If we are within any forall loop. */
88 static int forall_level
;
90 /* Keep track of whether we are within an OMP workshare. */
92 static bool in_omp_workshare
;
94 /* Keep track of whether we are within a WHERE statement. */
98 /* Keep track of iterators for array constructors. */
100 static int iterator_level
;
102 /* Keep track of DO loop levels. */
110 static vec
<do_t
> doloop_list
;
111 static int doloop_level
;
113 /* Keep track of if and select case levels. */
116 static int select_level
;
118 /* Vector of gfc_expr * to keep track of DO loops. */
120 struct my_struct
*evec
;
122 /* Keep track of association lists. */
124 static bool in_assoc_list
;
126 /* Counter for temporary variables. */
128 static int var_num
= 1;
130 /* What sort of matrix we are dealing with when inlining MATMUL. */
132 enum matrix_case
{ none
=0, A2B2
, A2B1
, A1B2
, A2B2T
, A2TB2
};
134 /* Keep track of the number of expressions we have inserted so far
139 /* Entry point - run all passes for a namespace. */
142 gfc_run_passes (gfc_namespace
*ns
)
145 /* Warn about dubious DO loops where the index might
152 doloop_list
.release ();
159 gfc_get_errors (&w
, &e
);
163 if (flag_frontend_optimize
|| flag_frontend_loop_interchange
)
164 optimize_namespace (ns
);
166 if (flag_frontend_optimize
)
168 optimize_reduction (ns
);
169 if (flag_dump_fortran_optimized
)
170 gfc_dump_parse_tree (ns
, stdout
);
172 expr_array
.release ();
175 if (flag_realloc_lhs
)
176 realloc_strings (ns
);
181 /* Callback function: Warn if there is no location information in a
185 check_locus_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
186 void *data ATTRIBUTE_UNUSED
)
189 if (c
&& *c
&& (((*c
)->loc
.nextc
== NULL
) || ((*c
)->loc
.lb
== NULL
)))
190 gfc_warning_internal (0, "No location in statement");
196 /* Callback function: Warn if there is no location information in an
200 check_locus_expr (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
201 void *data ATTRIBUTE_UNUSED
)
204 if (e
&& *e
&& (((*e
)->where
.nextc
== NULL
|| (*e
)->where
.lb
== NULL
)))
205 gfc_warning_internal (0, "No location in expression near %L",
206 &((*current_code
)->loc
));
210 /* Run check for missing location information. */
213 check_locus (gfc_namespace
*ns
)
215 gfc_code_walker (&ns
->code
, check_locus_code
, check_locus_expr
, NULL
);
217 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
219 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
226 /* Callback for each gfc_code node invoked from check_realloc_strings.
227 For an allocatable LHS string which also appears as a variable on
239 realloc_string_callback (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
240 void *data ATTRIBUTE_UNUSED
)
242 gfc_expr
*expr1
, *expr2
;
248 if (co
->op
!= EXEC_ASSIGN
)
252 if (expr1
->ts
.type
!= BT_CHARACTER
253 || !gfc_expr_attr(expr1
).allocatable
254 || !expr1
->ts
.deferred
)
257 expr2
= gfc_discard_nops (co
->expr2
);
259 if (expr2
->expr_type
== EXPR_VARIABLE
)
261 found_substr
= false;
262 for (ref
= expr2
->ref
; ref
; ref
= ref
->next
)
264 if (ref
->type
== REF_SUBSTRING
)
273 else if (expr2
->expr_type
!= EXPR_ARRAY
274 && (expr2
->expr_type
!= EXPR_OP
275 || expr2
->value
.op
.op
!= INTRINSIC_CONCAT
))
278 if (!gfc_check_dependency (expr1
, expr2
, true))
281 /* gfc_check_dependency doesn't always pick up identical expressions.
282 However, eliminating the above sends the compiler into an infinite
283 loop on valid expressions. Without this check, the gimplifier emits
284 an ICE for a = a, where a is deferred character length. */
285 if (!gfc_dep_compare_expr (expr1
, expr2
))
289 inserted_block
= NULL
;
290 changed_statement
= NULL
;
291 n
= create_var (expr2
, "realloc_string");
296 /* Callback for each gfc_code node invoked through gfc_code_walker
297 from optimize_namespace. */
300 optimize_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
301 void *data ATTRIBUTE_UNUSED
)
308 if (op
== EXEC_CALL
|| op
== EXEC_COMPCALL
|| op
== EXEC_ASSIGN_CALL
309 || op
== EXEC_CALL_PPC
)
315 inserted_block
= NULL
;
316 changed_statement
= NULL
;
318 if (op
== EXEC_ASSIGN
)
319 optimize_assignment (*c
);
323 /* Callback for each gfc_expr node invoked through gfc_code_walker
324 from optimize_namespace. */
327 optimize_expr (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
328 void *data ATTRIBUTE_UNUSED
)
332 if ((*e
)->expr_type
== EXPR_FUNCTION
)
335 function_expr
= true;
338 function_expr
= false;
340 if (optimize_trim (*e
))
341 gfc_simplify_expr (*e
, 0);
343 if (optimize_lexical_comparison (*e
))
344 gfc_simplify_expr (*e
, 0);
346 if ((*e
)->expr_type
== EXPR_OP
&& optimize_op (*e
))
347 gfc_simplify_expr (*e
, 0);
349 if ((*e
)->expr_type
== EXPR_FUNCTION
&& (*e
)->value
.function
.isym
)
350 switch ((*e
)->value
.function
.isym
->id
)
352 case GFC_ISYM_MINLOC
:
353 case GFC_ISYM_MAXLOC
:
354 optimize_minmaxloc (e
);
366 /* Auxiliary function to handle the arguments to reduction intrnisics. If the
367 function is a scalar, just copy it; otherwise returns the new element, the
368 old one can be freed. */
371 copy_walk_reduction_arg (gfc_constructor
*c
, gfc_expr
*fn
)
373 gfc_expr
*fcn
, *e
= c
->expr
;
375 fcn
= gfc_copy_expr (e
);
378 gfc_constructor_base newbase
;
380 gfc_constructor
*new_c
;
383 new_expr
= gfc_get_expr ();
384 new_expr
->expr_type
= EXPR_ARRAY
;
385 new_expr
->ts
= e
->ts
;
386 new_expr
->where
= e
->where
;
388 new_c
= gfc_constructor_append_expr (&newbase
, fcn
, &(e
->where
));
389 new_c
->iterator
= c
->iterator
;
390 new_expr
->value
.constructor
= newbase
;
398 gfc_isym_id id
= fn
->value
.function
.isym
->id
;
400 if (id
== GFC_ISYM_SUM
|| id
== GFC_ISYM_PRODUCT
)
401 fcn
= gfc_build_intrinsic_call (current_ns
, id
,
402 fn
->value
.function
.isym
->name
,
403 fn
->where
, 3, fcn
, NULL
, NULL
);
404 else if (id
== GFC_ISYM_ANY
|| id
== GFC_ISYM_ALL
)
405 fcn
= gfc_build_intrinsic_call (current_ns
, id
,
406 fn
->value
.function
.isym
->name
,
407 fn
->where
, 2, fcn
, NULL
);
409 gfc_internal_error ("Illegal id in copy_walk_reduction_arg");
411 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
417 /* Callback function for optimzation of reductions to scalars. Transform ANY
418 ([f1,f2,f3, ...]) to f1 .or. f2 .or. f3 .or. ..., with ANY, SUM and PRODUCT
419 correspondingly. Handly only the simple cases without MASK and DIM. */
422 callback_reduction (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
423 void *data ATTRIBUTE_UNUSED
)
428 gfc_actual_arglist
*a
;
429 gfc_actual_arglist
*dim
;
431 gfc_expr
*res
, *new_expr
;
432 gfc_actual_arglist
*mask
;
436 if (fn
->rank
!= 0 || fn
->expr_type
!= EXPR_FUNCTION
437 || fn
->value
.function
.isym
== NULL
)
440 id
= fn
->value
.function
.isym
->id
;
442 if (id
!= GFC_ISYM_SUM
&& id
!= GFC_ISYM_PRODUCT
443 && id
!= GFC_ISYM_ANY
&& id
!= GFC_ISYM_ALL
)
446 a
= fn
->value
.function
.actual
;
448 /* Don't handle MASK or DIM. */
452 if (dim
->expr
!= NULL
)
455 if (id
== GFC_ISYM_SUM
|| id
== GFC_ISYM_PRODUCT
)
458 if ( mask
->expr
!= NULL
)
464 if (arg
->expr_type
!= EXPR_ARRAY
)
473 case GFC_ISYM_PRODUCT
:
474 op
= INTRINSIC_TIMES
;
489 c
= gfc_constructor_first (arg
->value
.constructor
);
491 /* Don't do any simplififcation if we have
492 - no element in the constructor or
493 - only have a single element in the array which contains an
499 res
= copy_walk_reduction_arg (c
, fn
);
501 c
= gfc_constructor_next (c
);
504 new_expr
= gfc_get_expr ();
505 new_expr
->ts
= fn
->ts
;
506 new_expr
->expr_type
= EXPR_OP
;
507 new_expr
->rank
= fn
->rank
;
508 new_expr
->where
= fn
->where
;
509 new_expr
->value
.op
.op
= op
;
510 new_expr
->value
.op
.op1
= res
;
511 new_expr
->value
.op
.op2
= copy_walk_reduction_arg (c
, fn
);
513 c
= gfc_constructor_next (c
);
516 gfc_simplify_expr (res
, 0);
523 /* Callback function for common function elimination, called from cfe_expr_0.
524 Put all eligible function expressions into expr_array. */
527 cfe_register_funcs (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
528 void *data ATTRIBUTE_UNUSED
)
531 if ((*e
)->expr_type
!= EXPR_FUNCTION
)
534 /* We don't do character functions with unknown charlens. */
535 if ((*e
)->ts
.type
== BT_CHARACTER
536 && ((*e
)->ts
.u
.cl
== NULL
|| (*e
)->ts
.u
.cl
->length
== NULL
537 || (*e
)->ts
.u
.cl
->length
->expr_type
!= EXPR_CONSTANT
))
540 /* We don't do function elimination within FORALL statements, it can
541 lead to wrong-code in certain circumstances. */
543 if (forall_level
> 0)
546 /* Function elimination inside an iterator could lead to functions which
547 depend on iterator variables being moved outside. FIXME: We should check
548 if the functions do indeed depend on the iterator variable. */
550 if (iterator_level
> 0)
553 /* If we don't know the shape at compile time, we create an allocatable
554 temporary variable to hold the intermediate result, but only if
555 allocation on assignment is active. */
557 if ((*e
)->rank
> 0 && (*e
)->shape
== NULL
&& !flag_realloc_lhs
)
560 /* Skip the test for pure functions if -faggressive-function-elimination
562 if ((*e
)->value
.function
.esym
)
564 /* Don't create an array temporary for elemental functions. */
565 if ((*e
)->value
.function
.esym
->attr
.elemental
&& (*e
)->rank
> 0)
568 /* Only eliminate potentially impure functions if the
569 user specifically requested it. */
570 if (!flag_aggressive_function_elimination
571 && !(*e
)->value
.function
.esym
->attr
.pure
572 && !(*e
)->value
.function
.esym
->attr
.implicit_pure
)
576 if ((*e
)->value
.function
.isym
)
578 /* Conversions are handled on the fly by the middle end,
579 transpose during trans-* stages and TRANSFER by the middle end. */
580 if ((*e
)->value
.function
.isym
->id
== GFC_ISYM_CONVERSION
581 || (*e
)->value
.function
.isym
->id
== GFC_ISYM_TRANSFER
582 || gfc_inline_intrinsic_function_p (*e
))
585 /* Don't create an array temporary for elemental functions,
586 as this would be wasteful of memory.
587 FIXME: Create a scalar temporary during scalarization. */
588 if ((*e
)->value
.function
.isym
->elemental
&& (*e
)->rank
> 0)
591 if (!(*e
)->value
.function
.isym
->pure
)
595 expr_array
.safe_push (e
);
599 /* Auxiliary function to check if an expression is a temporary created by
603 is_fe_temp (gfc_expr
*e
)
605 if (e
->expr_type
!= EXPR_VARIABLE
)
608 return e
->symtree
->n
.sym
->attr
.fe_temp
;
611 /* Determine the length of a string, if it can be evaluated as a constant
612 expression. Return a newly allocated gfc_expr or NULL on failure.
613 If the user specified a substring which is potentially longer than
614 the string itself, the string will be padded with spaces, which
618 constant_string_length (gfc_expr
*e
)
628 length
= e
->ts
.u
.cl
->length
;
629 if (length
&& length
->expr_type
== EXPR_CONSTANT
)
630 return gfc_copy_expr(length
);
633 /* Return length of substring, if constant. */
634 for (ref
= e
->ref
; ref
; ref
= ref
->next
)
636 if (ref
->type
== REF_SUBSTRING
637 && gfc_dep_difference (ref
->u
.ss
.end
, ref
->u
.ss
.start
, &value
))
639 res
= gfc_get_constant_expr (BT_INTEGER
, gfc_charlen_int_kind
,
642 mpz_add_ui (res
->value
.integer
, value
, 1);
648 /* Return length of char symbol, if constant. */
650 if (e
->symtree
&& e
->symtree
->n
.sym
->ts
.u
.cl
651 && e
->symtree
->n
.sym
->ts
.u
.cl
->length
652 && e
->symtree
->n
.sym
->ts
.u
.cl
->length
->expr_type
== EXPR_CONSTANT
)
653 return gfc_copy_expr (e
->symtree
->n
.sym
->ts
.u
.cl
->length
);
659 /* Insert a block at the current position unless it has already
660 been inserted; in this case use the one already there. */
662 static gfc_namespace
*
667 /* If the block hasn't already been created, do so. */
668 if (inserted_block
== NULL
)
670 inserted_block
= XCNEW (gfc_code
);
671 inserted_block
->op
= EXEC_BLOCK
;
672 inserted_block
->loc
= (*current_code
)->loc
;
673 ns
= gfc_build_block_ns (current_ns
);
674 inserted_block
->ext
.block
.ns
= ns
;
675 inserted_block
->ext
.block
.assoc
= NULL
;
677 ns
->code
= *current_code
;
679 /* If the statement has a label, make sure it is transferred to
680 the newly created block. */
682 if ((*current_code
)->here
)
684 inserted_block
->here
= (*current_code
)->here
;
685 (*current_code
)->here
= NULL
;
688 inserted_block
->next
= (*current_code
)->next
;
689 changed_statement
= &(inserted_block
->ext
.block
.ns
->code
);
690 (*current_code
)->next
= NULL
;
691 /* Insert the BLOCK at the right position. */
692 *current_code
= inserted_block
;
693 ns
->parent
= current_ns
;
696 ns
= inserted_block
->ext
.block
.ns
;
701 /* Returns a new expression (a variable) to be used in place of the old one,
702 with an optional assignment statement before the current statement to set
703 the value of the variable. Creates a new BLOCK for the statement if that
704 hasn't already been done and puts the statement, plus the newly created
705 variables, in that block. Special cases: If the expression is constant or
706 a temporary which has already been created, just copy it. */
709 create_var (gfc_expr
* e
, const char *vname
)
711 char name
[GFC_MAX_SYMBOL_LEN
+1];
712 gfc_symtree
*symtree
;
720 if (e
->expr_type
== EXPR_CONSTANT
|| is_fe_temp (e
))
721 return gfc_copy_expr (e
);
723 /* Creation of an array of unknown size requires realloc on assignment.
724 If that is not possible, just return NULL. */
725 if (flag_realloc_lhs
== 0 && e
->rank
> 0 && e
->shape
== NULL
)
728 ns
= insert_block ();
731 snprintf (name
, GFC_MAX_SYMBOL_LEN
, "__var_%d_%s", var_num
++, vname
);
733 snprintf (name
, GFC_MAX_SYMBOL_LEN
, "__var_%d", var_num
++);
735 if (gfc_get_sym_tree (name
, ns
, &symtree
, false) != 0)
738 symbol
= symtree
->n
.sym
;
743 symbol
->as
= gfc_get_array_spec ();
744 symbol
->as
->rank
= e
->rank
;
746 if (e
->shape
== NULL
)
748 /* We don't know the shape at compile time, so we use an
750 symbol
->as
->type
= AS_DEFERRED
;
751 symbol
->attr
.allocatable
= 1;
755 symbol
->as
->type
= AS_EXPLICIT
;
756 /* Copy the shape. */
757 for (i
=0; i
<e
->rank
; i
++)
761 p
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
763 mpz_set_si (p
->value
.integer
, 1);
764 symbol
->as
->lower
[i
] = p
;
766 q
= gfc_get_constant_expr (BT_INTEGER
, gfc_index_integer_kind
,
768 mpz_set (q
->value
.integer
, e
->shape
[i
]);
769 symbol
->as
->upper
[i
] = q
;
775 if (e
->ts
.type
== BT_CHARACTER
)
779 symbol
->ts
.u
.cl
= gfc_new_charlen (ns
, NULL
);
780 length
= constant_string_length (e
);
782 symbol
->ts
.u
.cl
->length
= length
;
785 symbol
->attr
.allocatable
= 1;
786 symbol
->ts
.u
.cl
->length
= NULL
;
787 symbol
->ts
.deferred
= 1;
792 symbol
->attr
.flavor
= FL_VARIABLE
;
793 symbol
->attr
.referenced
= 1;
794 symbol
->attr
.dimension
= e
->rank
> 0;
795 symbol
->attr
.fe_temp
= 1;
796 gfc_commit_symbol (symbol
);
798 result
= gfc_get_expr ();
799 result
->expr_type
= EXPR_VARIABLE
;
800 result
->ts
= symbol
->ts
;
801 result
->ts
.deferred
= deferred
;
802 result
->rank
= e
->rank
;
803 result
->shape
= gfc_copy_shape (e
->shape
, e
->rank
);
804 result
->symtree
= symtree
;
805 result
->where
= e
->where
;
808 result
->ref
= gfc_get_ref ();
809 result
->ref
->type
= REF_ARRAY
;
810 result
->ref
->u
.ar
.type
= AR_FULL
;
811 result
->ref
->u
.ar
.where
= e
->where
;
812 result
->ref
->u
.ar
.dimen
= e
->rank
;
813 result
->ref
->u
.ar
.as
= symbol
->ts
.type
== BT_CLASS
814 ? CLASS_DATA (symbol
)->as
: symbol
->as
;
815 if (warn_array_temporaries
)
816 gfc_warning (OPT_Warray_temporaries
,
817 "Creating array temporary at %L", &(e
->where
));
820 /* Generate the new assignment. */
821 n
= XCNEW (gfc_code
);
823 n
->loc
= (*current_code
)->loc
;
824 n
->next
= *changed_statement
;
825 n
->expr1
= gfc_copy_expr (result
);
827 *changed_statement
= n
;
833 /* Warn about function elimination. */
836 do_warn_function_elimination (gfc_expr
*e
)
838 if (e
->expr_type
!= EXPR_FUNCTION
)
840 if (e
->value
.function
.esym
)
841 gfc_warning (OPT_Wfunction_elimination
,
842 "Removing call to function %qs at %L",
843 e
->value
.function
.esym
->name
, &(e
->where
));
844 else if (e
->value
.function
.isym
)
845 gfc_warning (OPT_Wfunction_elimination
,
846 "Removing call to function %qs at %L",
847 e
->value
.function
.isym
->name
, &(e
->where
));
849 /* Callback function for the code walker for doing common function
850 elimination. This builds up the list of functions in the expression
851 and goes through them to detect duplicates, which it then replaces
855 cfe_expr_0 (gfc_expr
**e
, int *walk_subtrees
,
856 void *data ATTRIBUTE_UNUSED
)
862 /* Don't do this optimization within OMP workshare or ASSOC lists. */
864 if (in_omp_workshare
|| in_assoc_list
)
870 expr_array
.release ();
872 gfc_expr_walker (e
, cfe_register_funcs
, NULL
);
874 /* Walk through all the functions. */
876 FOR_EACH_VEC_ELT_FROM (expr_array
, i
, ei
, 1)
878 /* Skip if the function has been replaced by a variable already. */
879 if ((*ei
)->expr_type
== EXPR_VARIABLE
)
886 if (gfc_dep_compare_functions (*ei
, *ej
, true) == 0)
889 newvar
= create_var (*ei
, "fcn");
891 if (warn_function_elimination
)
892 do_warn_function_elimination (*ej
);
895 *ej
= gfc_copy_expr (newvar
);
902 /* We did all the necessary walking in this function. */
907 /* Callback function for common function elimination, called from
908 gfc_code_walker. This keeps track of the current code, in order
909 to insert statements as needed. */
912 cfe_code (gfc_code
**c
, int *walk_subtrees
, void *data ATTRIBUTE_UNUSED
)
915 inserted_block
= NULL
;
916 changed_statement
= NULL
;
918 /* Do not do anything inside a WHERE statement; scalar assignments, BLOCKs
919 and allocation on assigment are prohibited inside WHERE, and finally
920 masking an expression would lead to wrong-code when replacing
923 b = sum(foo(a) + foo(a))
934 if ((*c
)->op
== EXEC_WHERE
)
944 /* Dummy function for expression call back, for use when we
945 really don't want to do any walking. */
948 dummy_expr_callback (gfc_expr
**e ATTRIBUTE_UNUSED
, int *walk_subtrees
,
949 void *data ATTRIBUTE_UNUSED
)
955 /* Dummy function for code callback, for use when we really
956 don't want to do anything. */
958 gfc_dummy_code_callback (gfc_code
**e ATTRIBUTE_UNUSED
,
959 int *walk_subtrees ATTRIBUTE_UNUSED
,
960 void *data ATTRIBUTE_UNUSED
)
965 /* Code callback function for converting
972 This is because common function elimination would otherwise place the
973 temporary variables outside the loop. */
976 convert_do_while (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
977 void *data ATTRIBUTE_UNUSED
)
980 gfc_code
*c_if1
, *c_if2
, *c_exit
;
982 gfc_expr
*e_not
, *e_cond
;
984 if (co
->op
!= EXEC_DO_WHILE
)
987 if (co
->expr1
== NULL
|| co
->expr1
->expr_type
== EXPR_CONSTANT
)
992 /* Generate the condition of the if statement, which is .not. the original
994 e_not
= gfc_get_expr ();
995 e_not
->ts
= e_cond
->ts
;
996 e_not
->where
= e_cond
->where
;
997 e_not
->expr_type
= EXPR_OP
;
998 e_not
->value
.op
.op
= INTRINSIC_NOT
;
999 e_not
->value
.op
.op1
= e_cond
;
1001 /* Generate the EXIT statement. */
1002 c_exit
= XCNEW (gfc_code
);
1003 c_exit
->op
= EXEC_EXIT
;
1004 c_exit
->ext
.which_construct
= co
;
1005 c_exit
->loc
= co
->loc
;
1007 /* Generate the IF statement. */
1008 c_if2
= XCNEW (gfc_code
);
1009 c_if2
->op
= EXEC_IF
;
1010 c_if2
->expr1
= e_not
;
1011 c_if2
->next
= c_exit
;
1012 c_if2
->loc
= co
->loc
;
1014 /* ... plus the one to chain it to. */
1015 c_if1
= XCNEW (gfc_code
);
1016 c_if1
->op
= EXEC_IF
;
1017 c_if1
->block
= c_if2
;
1018 c_if1
->loc
= co
->loc
;
1020 /* Make the DO WHILE loop into a DO block by replacing the condition
1021 with a true constant. */
1022 co
->expr1
= gfc_get_logical_expr (gfc_default_integer_kind
, &co
->loc
, true);
1024 /* Hang the generated if statement into the loop body. */
1026 loopblock
= co
->block
->next
;
1027 co
->block
->next
= c_if1
;
1028 c_if1
->next
= loopblock
;
1033 /* Code callback function for converting
1046 because otherwise common function elimination would place the BLOCKs
1047 into the wrong place. */
1050 convert_elseif (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
1051 void *data ATTRIBUTE_UNUSED
)
1054 gfc_code
*c_if1
, *c_if2
, *else_stmt
;
1056 if (co
->op
!= EXEC_IF
)
1059 /* This loop starts out with the first ELSE statement. */
1060 else_stmt
= co
->block
->block
;
1062 while (else_stmt
!= NULL
)
1064 gfc_code
*next_else
;
1066 /* If there is no condition, we're done. */
1067 if (else_stmt
->expr1
== NULL
)
1070 next_else
= else_stmt
->block
;
1072 /* Generate the new IF statement. */
1073 c_if2
= XCNEW (gfc_code
);
1074 c_if2
->op
= EXEC_IF
;
1075 c_if2
->expr1
= else_stmt
->expr1
;
1076 c_if2
->next
= else_stmt
->next
;
1077 c_if2
->loc
= else_stmt
->loc
;
1078 c_if2
->block
= next_else
;
1080 /* ... plus the one to chain it to. */
1081 c_if1
= XCNEW (gfc_code
);
1082 c_if1
->op
= EXEC_IF
;
1083 c_if1
->block
= c_if2
;
1084 c_if1
->loc
= else_stmt
->loc
;
1086 /* Insert the new IF after the ELSE. */
1087 else_stmt
->expr1
= NULL
;
1088 else_stmt
->next
= c_if1
;
1089 else_stmt
->block
= NULL
;
1091 else_stmt
= next_else
;
1093 /* Don't walk subtrees. */
1099 struct do_stack
*prev
;
1104 /* Recursively traverse the block of a WRITE or READ statement, and maybe
1105 optimize by replacing do loops with their analog array slices. For
1108 write (*,*) (a(i), i=1,4)
1112 write (*,*) a(1:4:1) . */
1115 traverse_io_block (gfc_code
*code
, bool *has_reached
, gfc_code
*prev
)
1118 gfc_expr
*new_e
, *expr
, *start
;
1120 struct do_stack ds_push
;
1121 int i
, future_rank
= 0;
1122 gfc_iterator
*iters
[GFC_MAX_DIMENSIONS
];
1125 /* Find the first transfer/do statement. */
1126 for (curr
= code
; curr
; curr
= curr
->next
)
1128 if (curr
->op
== EXEC_DO
|| curr
->op
== EXEC_TRANSFER
)
1132 /* Ensure it is the only transfer/do statement because cases like
1134 write (*,*) (a(i), b(i), i=1,4)
1136 cannot be optimized. */
1138 if (!curr
|| curr
->next
)
1141 if (curr
->op
== EXEC_DO
)
1143 if (curr
->ext
.iterator
->var
->ref
)
1145 ds_push
.prev
= stack_top
;
1146 ds_push
.iter
= curr
->ext
.iterator
;
1147 ds_push
.code
= curr
;
1148 stack_top
= &ds_push
;
1149 if (traverse_io_block (curr
->block
->next
, has_reached
, prev
))
1151 if (curr
!= stack_top
->code
&& !*has_reached
)
1153 curr
->block
->next
= NULL
;
1154 gfc_free_statements (curr
);
1157 *has_reached
= true;
1163 gcc_assert (curr
->op
== EXEC_TRANSFER
);
1167 if (!ref
|| ref
->type
!= REF_ARRAY
|| ref
->u
.ar
.codimen
!= 0 || ref
->next
)
1170 /* Find the iterators belonging to each variable and check conditions. */
1171 for (i
= 0; i
< ref
->u
.ar
.dimen
; i
++)
1173 if (!ref
->u
.ar
.start
[i
] || ref
->u
.ar
.start
[i
]->ref
1174 || ref
->u
.ar
.dimen_type
[i
] != DIMEN_ELEMENT
)
1177 start
= ref
->u
.ar
.start
[i
];
1178 gfc_simplify_expr (start
, 0);
1179 switch (start
->expr_type
)
1183 /* write (*,*) (a(i), i=a%b,1) not handled yet. */
1187 /* Check for (a(k), i=1,4) or ((a(j, i), i=1,4), j=1,4). */
1188 if (!stack_top
|| !stack_top
->iter
1189 || stack_top
->iter
->var
->symtree
!= start
->symtree
)
1191 /* Check for (a(i,i), i=1,3). */
1195 if (iters
[j
] && iters
[j
]->var
->symtree
== start
->symtree
)
1202 iters
[i
] = stack_top
->iter
;
1203 stack_top
= stack_top
->prev
;
1211 switch (start
->value
.op
.op
)
1213 case INTRINSIC_PLUS
:
1214 case INTRINSIC_TIMES
:
1215 if (start
->value
.op
.op1
->expr_type
!= EXPR_VARIABLE
)
1216 std::swap (start
->value
.op
.op1
, start
->value
.op
.op2
);
1218 case INTRINSIC_MINUS
:
1219 if ((start
->value
.op
.op1
->expr_type
!= EXPR_VARIABLE
1220 && start
->value
.op
.op2
->expr_type
!= EXPR_CONSTANT
)
1221 || start
->value
.op
.op1
->ref
)
1223 if (!stack_top
|| !stack_top
->iter
1224 || stack_top
->iter
->var
->symtree
1225 != start
->value
.op
.op1
->symtree
)
1227 iters
[i
] = stack_top
->iter
;
1228 stack_top
= stack_top
->prev
;
1240 /* Check for cases like ((a(i, j), i=1, j), j=1, 2). */
1241 for (int i
= 1; i
< ref
->u
.ar
.dimen
; i
++)
1245 gfc_expr
*var
= iters
[i
]->var
;
1246 for (int j
= i
- 1; j
< i
; j
++)
1249 && (gfc_check_dependency (var
, iters
[j
]->start
, true)
1250 || gfc_check_dependency (var
, iters
[j
]->end
, true)
1251 || gfc_check_dependency (var
, iters
[j
]->step
, true)))
1257 /* Create new expr. */
1258 new_e
= gfc_copy_expr (curr
->expr1
);
1259 new_e
->expr_type
= EXPR_VARIABLE
;
1260 new_e
->rank
= future_rank
;
1261 if (curr
->expr1
->shape
)
1262 new_e
->shape
= gfc_get_shape (new_e
->rank
);
1264 /* Assign new starts, ends and strides if necessary. */
1265 for (i
= 0; i
< ref
->u
.ar
.dimen
; i
++)
1269 start
= ref
->u
.ar
.start
[i
];
1270 switch (start
->expr_type
)
1273 gfc_internal_error ("bad expression");
1276 new_e
->ref
->u
.ar
.dimen_type
[i
] = DIMEN_RANGE
;
1277 new_e
->ref
->u
.ar
.type
= AR_SECTION
;
1278 gfc_free_expr (new_e
->ref
->u
.ar
.start
[i
]);
1279 new_e
->ref
->u
.ar
.start
[i
] = gfc_copy_expr (iters
[i
]->start
);
1280 new_e
->ref
->u
.ar
.end
[i
] = gfc_copy_expr (iters
[i
]->end
);
1281 new_e
->ref
->u
.ar
.stride
[i
] = gfc_copy_expr (iters
[i
]->step
);
1284 new_e
->ref
->u
.ar
.dimen_type
[i
] = DIMEN_RANGE
;
1285 new_e
->ref
->u
.ar
.type
= AR_SECTION
;
1286 gfc_free_expr (new_e
->ref
->u
.ar
.start
[i
]);
1287 expr
= gfc_copy_expr (start
);
1288 expr
->value
.op
.op1
= gfc_copy_expr (iters
[i
]->start
);
1289 new_e
->ref
->u
.ar
.start
[i
] = expr
;
1290 gfc_simplify_expr (new_e
->ref
->u
.ar
.start
[i
], 0);
1291 expr
= gfc_copy_expr (start
);
1292 expr
->value
.op
.op1
= gfc_copy_expr (iters
[i
]->end
);
1293 new_e
->ref
->u
.ar
.end
[i
] = expr
;
1294 gfc_simplify_expr (new_e
->ref
->u
.ar
.end
[i
], 0);
1295 switch (start
->value
.op
.op
)
1297 case INTRINSIC_MINUS
:
1298 case INTRINSIC_PLUS
:
1299 new_e
->ref
->u
.ar
.stride
[i
] = gfc_copy_expr (iters
[i
]->step
);
1301 case INTRINSIC_TIMES
:
1302 expr
= gfc_copy_expr (start
);
1303 expr
->value
.op
.op1
= gfc_copy_expr (iters
[i
]->step
);
1304 new_e
->ref
->u
.ar
.stride
[i
] = expr
;
1305 gfc_simplify_expr (new_e
->ref
->u
.ar
.stride
[i
], 0);
1308 gfc_internal_error ("bad op");
1312 gfc_internal_error ("bad expression");
1315 curr
->expr1
= new_e
;
1317 /* Insert modified statement. Check whether the statement needs to be
1318 inserted at the lowest level. */
1319 if (!stack_top
->iter
)
1323 curr
->next
= prev
->next
->next
;
1328 curr
->next
= stack_top
->code
->block
->next
->next
->next
;
1329 stack_top
->code
->block
->next
= curr
;
1333 stack_top
->code
->block
->next
= curr
;
1337 /* Function for the gfc_code_walker. If code is a READ or WRITE statement, it
1338 tries to optimize its block. */
1341 simplify_io_impl_do (gfc_code
**code
, int *walk_subtrees
,
1342 void *data ATTRIBUTE_UNUSED
)
1344 gfc_code
**curr
, *prev
= NULL
;
1345 struct do_stack write
, first
;
1349 || ((*code
)->block
->op
!= EXEC_WRITE
1350 && (*code
)->block
->op
!= EXEC_READ
))
1358 for (curr
= &(*code
)->block
; *curr
; curr
= &(*curr
)->next
)
1360 if ((*curr
)->op
== EXEC_DO
)
1362 first
.prev
= &write
;
1363 first
.iter
= (*curr
)->ext
.iterator
;
1366 traverse_io_block ((*curr
)->block
->next
, &b
, prev
);
1374 /* Optimize a namespace, including all contained namespaces.
1375 flag_frontend_optimize and flag_fronend_loop_interchange are
1376 handled separately. */
1379 optimize_namespace (gfc_namespace
*ns
)
1381 gfc_namespace
*saved_ns
= gfc_current_ns
;
1383 gfc_current_ns
= ns
;
1386 in_assoc_list
= false;
1387 in_omp_workshare
= false;
1389 if (flag_frontend_optimize
)
1391 gfc_code_walker (&ns
->code
, simplify_io_impl_do
, dummy_expr_callback
, NULL
);
1392 gfc_code_walker (&ns
->code
, convert_do_while
, dummy_expr_callback
, NULL
);
1393 gfc_code_walker (&ns
->code
, convert_elseif
, dummy_expr_callback
, NULL
);
1394 gfc_code_walker (&ns
->code
, cfe_code
, cfe_expr_0
, NULL
);
1395 gfc_code_walker (&ns
->code
, optimize_code
, optimize_expr
, NULL
);
1396 if (flag_inline_matmul_limit
!= 0)
1402 gfc_code_walker (&ns
->code
, matmul_to_var_code
, matmul_to_var_expr
,
1407 gfc_code_walker (&ns
->code
, matmul_temp_args
, dummy_expr_callback
,
1409 gfc_code_walker (&ns
->code
, inline_matmul_assign
, dummy_expr_callback
,
1414 if (flag_frontend_loop_interchange
)
1415 gfc_code_walker (&ns
->code
, index_interchange
, dummy_expr_callback
,
1418 /* BLOCKs are handled in the expression walker below. */
1419 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
1421 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
1422 optimize_namespace (ns
);
1424 gfc_current_ns
= saved_ns
;
1427 /* Handle dependencies for allocatable strings which potentially redefine
1428 themselves in an assignment. */
1431 realloc_strings (gfc_namespace
*ns
)
1434 gfc_code_walker (&ns
->code
, realloc_string_callback
, dummy_expr_callback
, NULL
);
1436 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
1438 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
1439 realloc_strings (ns
);
1445 optimize_reduction (gfc_namespace
*ns
)
1448 gfc_code_walker (&ns
->code
, gfc_dummy_code_callback
,
1449 callback_reduction
, NULL
);
1451 /* BLOCKs are handled in the expression walker below. */
1452 for (ns
= ns
->contained
; ns
; ns
= ns
->sibling
)
1454 if (ns
->code
== NULL
|| ns
->code
->op
!= EXEC_BLOCK
)
1455 optimize_reduction (ns
);
1459 /* Replace code like
1462 a = matmul(b,c) ; a = a + d
1463 where the array function is not elemental and not allocatable
1464 and does not depend on the left-hand side.
1468 optimize_binop_array_assignment (gfc_code
*c
, gfc_expr
**rhs
, bool seen_op
)
1476 if (e
->expr_type
== EXPR_OP
)
1478 switch (e
->value
.op
.op
)
1480 /* Unary operators and exponentiation: Only look at a single
1483 case INTRINSIC_UPLUS
:
1484 case INTRINSIC_UMINUS
:
1485 case INTRINSIC_PARENTHESES
:
1486 case INTRINSIC_POWER
:
1487 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, seen_op
))
1491 case INTRINSIC_CONCAT
:
1492 /* Do not do string concatenations. */
1496 /* Binary operators. */
1497 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op1
, true))
1500 if (optimize_binop_array_assignment (c
, &e
->value
.op
.op2
, true))
1506 else if (seen_op
&& e
->expr_type
== EXPR_FUNCTION
&& e
->rank
> 0
1507 && ! (e
->value
.function
.esym
1508 && (e
->value
.function
.esym
->attr
.elemental
1509 || e
->value
.function
.esym
->attr
.allocatable
1510 || e
->value
.function
.esym
->ts
.type
!= c
->expr1
->ts
.type
1511 || e
->value
.function
.esym
->ts
.kind
!= c
->expr1
->ts
.kind
))
1512 && ! (e
->value
.function
.isym
1513 && (e
->value
.function
.isym
->elemental
1514 || e
->ts
.type
!= c
->expr1
->ts
.type
1515 || e
->ts
.kind
!= c
->expr1
->ts
.kind
))
1516 && ! gfc_inline_intrinsic_function_p (e
))
1522 /* Insert a new assignment statement after the current one. */
1523 n
= XCNEW (gfc_code
);
1524 n
->op
= EXEC_ASSIGN
;
1529 n
->expr1
= gfc_copy_expr (c
->expr1
);
1530 n
->expr2
= c
->expr2
;
1531 new_expr
= gfc_copy_expr (c
->expr1
);
1539 /* Nothing to optimize. */
1543 /* Remove unneeded TRIMs at the end of expressions. */
1546 remove_trim (gfc_expr
*rhs
)
1554 /* Check for a // b // trim(c). Looping is probably not
1555 necessary because the parser usually generates
1556 (// (// a b ) trim(c) ) , but better safe than sorry. */
1558 while (rhs
->expr_type
== EXPR_OP
1559 && rhs
->value
.op
.op
== INTRINSIC_CONCAT
)
1560 rhs
= rhs
->value
.op
.op2
;
1562 while (rhs
->expr_type
== EXPR_FUNCTION
&& rhs
->value
.function
.isym
1563 && rhs
->value
.function
.isym
->id
== GFC_ISYM_TRIM
)
1565 strip_function_call (rhs
);
1566 /* Recursive call to catch silly stuff like trim ( a // trim(b)). */
1574 /* Optimizations for an assignment. */
1577 optimize_assignment (gfc_code
* c
)
1579 gfc_expr
*lhs
, *rhs
;
1584 if (lhs
->ts
.type
== BT_CHARACTER
&& !lhs
->ts
.deferred
)
1586 /* Optimize a = trim(b) to a = b. */
1589 /* Replace a = ' ' by a = '' to optimize away a memcpy. */
1590 if (is_empty_string (rhs
))
1591 rhs
->value
.character
.length
= 0;
1594 if (lhs
->rank
> 0 && gfc_check_dependency (lhs
, rhs
, true) == 0)
1595 optimize_binop_array_assignment (c
, &rhs
, false);
1599 /* Remove an unneeded function call, modifying the expression.
1600 This replaces the function call with the value of its
1601 first argument. The rest of the argument list is freed. */
1604 strip_function_call (gfc_expr
*e
)
1607 gfc_actual_arglist
*a
;
1609 a
= e
->value
.function
.actual
;
1611 /* We should have at least one argument. */
1612 gcc_assert (a
->expr
!= NULL
);
1616 /* Free the remaining arglist, if any. */
1618 gfc_free_actual_arglist (a
->next
);
1620 /* Graft the argument expression onto the original function. */
1626 /* Optimization of lexical comparison functions. */
1629 optimize_lexical_comparison (gfc_expr
*e
)
1631 if (e
->expr_type
!= EXPR_FUNCTION
|| e
->value
.function
.isym
== NULL
)
1634 switch (e
->value
.function
.isym
->id
)
1637 return optimize_comparison (e
, INTRINSIC_LE
);
1640 return optimize_comparison (e
, INTRINSIC_GE
);
1643 return optimize_comparison (e
, INTRINSIC_GT
);
1646 return optimize_comparison (e
, INTRINSIC_LT
);
1654 /* Combine stuff like [a]>b into [a>b], for easier optimization later. Do not
1655 do CHARACTER because of possible pessimization involving character
1659 combine_array_constructor (gfc_expr
*e
)
1662 gfc_expr
*op1
, *op2
;
1665 gfc_constructor
*c
, *new_c
;
1666 gfc_constructor_base oldbase
, newbase
;
1671 /* Array constructors have rank one. */
1675 /* Don't try to combine association lists, this makes no sense
1676 and leads to an ICE. */
1680 /* With FORALL, the BLOCKS created by create_var will cause an ICE. */
1681 if (forall_level
> 0)
1684 /* Inside an iterator, things can get hairy; we are likely to create
1685 an invalid temporary variable. */
1686 if (iterator_level
> 0)
1689 op1
= e
->value
.op
.op1
;
1690 op2
= e
->value
.op
.op2
;
1695 if (op1
->expr_type
== EXPR_ARRAY
&& op2
->rank
== 0)
1696 scalar_first
= false;
1697 else if (op2
->expr_type
== EXPR_ARRAY
&& op1
->rank
== 0)
1699 scalar_first
= true;
1700 op1
= e
->value
.op
.op2
;
1701 op2
= e
->value
.op
.op1
;
1706 if (op2
->ts
.type
== BT_CHARACTER
)
1709 /* This might be an expanded constructor with very many constant values. If
1710 we perform the operation here, we might end up with a long compile time
1711 and actually longer execution time, so a length bound is in order here.
1712 If the constructor constains something which is not a constant, it did
1713 not come from an expansion, so leave it alone. */
1715 #define CONSTR_LEN_MAX 4
1717 oldbase
= op1
->value
.constructor
;
1721 for (c
= gfc_constructor_first (oldbase
); c
; c
= gfc_constructor_next(c
))
1723 if (c
->expr
->expr_type
!= EXPR_CONSTANT
)
1731 if (all_const
&& n_elem
> CONSTR_LEN_MAX
)
1734 #undef CONSTR_LEN_MAX
1737 e
->expr_type
= EXPR_ARRAY
;
1739 scalar
= create_var (gfc_copy_expr (op2
), "constr");
1741 for (c
= gfc_constructor_first (oldbase
); c
;
1742 c
= gfc_constructor_next (c
))
1744 new_expr
= gfc_get_expr ();
1745 new_expr
->ts
= e
->ts
;
1746 new_expr
->expr_type
= EXPR_OP
;
1747 new_expr
->rank
= c
->expr
->rank
;
1748 new_expr
->where
= c
->expr
->where
;
1749 new_expr
->value
.op
.op
= e
->value
.op
.op
;
1753 new_expr
->value
.op
.op1
= gfc_copy_expr (scalar
);
1754 new_expr
->value
.op
.op2
= gfc_copy_expr (c
->expr
);
1758 new_expr
->value
.op
.op1
= gfc_copy_expr (c
->expr
);
1759 new_expr
->value
.op
.op2
= gfc_copy_expr (scalar
);
1762 new_c
= gfc_constructor_append_expr (&newbase
, new_expr
, &(e
->where
));
1763 new_c
->iterator
= c
->iterator
;
1767 gfc_free_expr (op1
);
1768 gfc_free_expr (op2
);
1769 gfc_free_expr (scalar
);
1771 e
->value
.constructor
= newbase
;
1775 /* Change (-1)**k into 1-ishift(iand(k,1),1) and
1776 2**k into ishift(1,k) */
1779 optimize_power (gfc_expr
*e
)
1781 gfc_expr
*op1
, *op2
;
1782 gfc_expr
*iand
, *ishft
;
1784 if (e
->ts
.type
!= BT_INTEGER
)
1787 op1
= e
->value
.op
.op1
;
1789 if (op1
== NULL
|| op1
->expr_type
!= EXPR_CONSTANT
)
1792 if (mpz_cmp_si (op1
->value
.integer
, -1L) == 0)
1794 gfc_free_expr (op1
);
1796 op2
= e
->value
.op
.op2
;
1801 iand
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_IAND
,
1802 "_internal_iand", e
->where
, 2, op2
,
1803 gfc_get_int_expr (e
->ts
.kind
,
1806 ishft
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ISHFT
,
1807 "_internal_ishft", e
->where
, 2, iand
,
1808 gfc_get_int_expr (e
->ts
.kind
,
1811 e
->value
.op
.op
= INTRINSIC_MINUS
;
1812 e
->value
.op
.op1
= gfc_get_int_expr (e
->ts
.kind
, &e
->where
, 1);
1813 e
->value
.op
.op2
= ishft
;
1816 else if (mpz_cmp_si (op1
->value
.integer
, 2L) == 0)
1818 gfc_free_expr (op1
);
1820 op2
= e
->value
.op
.op2
;
1824 ishft
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ISHFT
,
1825 "_internal_ishft", e
->where
, 2,
1826 gfc_get_int_expr (e
->ts
.kind
,
1833 else if (mpz_cmp_si (op1
->value
.integer
, 1L) == 0)
1835 op2
= e
->value
.op
.op2
;
1839 gfc_free_expr (op1
);
1840 gfc_free_expr (op2
);
1842 e
->expr_type
= EXPR_CONSTANT
;
1843 e
->value
.op
.op1
= NULL
;
1844 e
->value
.op
.op2
= NULL
;
1845 mpz_init_set_si (e
->value
.integer
, 1);
1846 /* Typespec and location are still OK. */
1853 /* Recursive optimization of operators. */
1856 optimize_op (gfc_expr
*e
)
1860 gfc_intrinsic_op op
= e
->value
.op
.op
;
1864 /* Only use new-style comparisons. */
1867 case INTRINSIC_EQ_OS
:
1871 case INTRINSIC_GE_OS
:
1875 case INTRINSIC_LE_OS
:
1879 case INTRINSIC_NE_OS
:
1883 case INTRINSIC_GT_OS
:
1887 case INTRINSIC_LT_OS
:
1903 changed
= optimize_comparison (e
, op
);
1906 /* Look at array constructors. */
1907 case INTRINSIC_PLUS
:
1908 case INTRINSIC_MINUS
:
1909 case INTRINSIC_TIMES
:
1910 case INTRINSIC_DIVIDE
:
1911 return combine_array_constructor (e
) || changed
;
1913 case INTRINSIC_POWER
:
1914 return optimize_power (e
);
1924 /* Return true if a constant string contains only blanks. */
1927 is_empty_string (gfc_expr
*e
)
1931 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_CONSTANT
)
1934 for (i
=0; i
< e
->value
.character
.length
; i
++)
1936 if (e
->value
.character
.string
[i
] != ' ')
1944 /* Insert a call to the intrinsic len_trim. Use a different name for
1945 the symbol tree so we don't run into trouble when the user has
1946 renamed len_trim for some reason. */
1949 get_len_trim_call (gfc_expr
*str
, int kind
)
1952 gfc_actual_arglist
*actual_arglist
, *next
;
1954 fcn
= gfc_get_expr ();
1955 fcn
->expr_type
= EXPR_FUNCTION
;
1956 fcn
->value
.function
.isym
= gfc_intrinsic_function_by_id (GFC_ISYM_LEN_TRIM
);
1957 actual_arglist
= gfc_get_actual_arglist ();
1958 actual_arglist
->expr
= str
;
1959 next
= gfc_get_actual_arglist ();
1960 next
->expr
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
, kind
);
1961 actual_arglist
->next
= next
;
1963 fcn
->value
.function
.actual
= actual_arglist
;
1964 fcn
->where
= str
->where
;
1965 fcn
->ts
.type
= BT_INTEGER
;
1966 fcn
->ts
.kind
= gfc_charlen_int_kind
;
1968 gfc_get_sym_tree ("__internal_len_trim", current_ns
, &fcn
->symtree
, false);
1969 fcn
->symtree
->n
.sym
->ts
= fcn
->ts
;
1970 fcn
->symtree
->n
.sym
->attr
.flavor
= FL_PROCEDURE
;
1971 fcn
->symtree
->n
.sym
->attr
.function
= 1;
1972 fcn
->symtree
->n
.sym
->attr
.elemental
= 1;
1973 fcn
->symtree
->n
.sym
->attr
.referenced
= 1;
1974 fcn
->symtree
->n
.sym
->attr
.access
= ACCESS_PRIVATE
;
1975 gfc_commit_symbol (fcn
->symtree
->n
.sym
);
1980 /* Optimize expressions for equality. */
1983 optimize_comparison (gfc_expr
*e
, gfc_intrinsic_op op
)
1985 gfc_expr
*op1
, *op2
;
1989 gfc_actual_arglist
*firstarg
, *secondarg
;
1991 if (e
->expr_type
== EXPR_OP
)
1995 op1
= e
->value
.op
.op1
;
1996 op2
= e
->value
.op
.op2
;
1998 else if (e
->expr_type
== EXPR_FUNCTION
)
2000 /* One of the lexical comparison functions. */
2001 firstarg
= e
->value
.function
.actual
;
2002 secondarg
= firstarg
->next
;
2003 op1
= firstarg
->expr
;
2004 op2
= secondarg
->expr
;
2009 /* Strip off unneeded TRIM calls from string comparisons. */
2011 change
= remove_trim (op1
);
2013 if (remove_trim (op2
))
2016 /* An expression of type EXPR_CONSTANT is only valid for scalars. */
2017 /* TODO: A scalar constant may be acceptable in some cases (the scalarizer
2018 handles them well). However, there are also cases that need a non-scalar
2019 argument. For example the any intrinsic. See PR 45380. */
2023 /* Replace a == '' with len_trim(a) == 0 and a /= '' with
2025 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
2026 && (op
== INTRINSIC_EQ
|| op
== INTRINSIC_NE
))
2028 bool empty_op1
, empty_op2
;
2029 empty_op1
= is_empty_string (op1
);
2030 empty_op2
= is_empty_string (op2
);
2032 if (empty_op1
|| empty_op2
)
2038 /* This can only happen when an error for comparing
2039 characters of different kinds has already been issued. */
2040 if (empty_op1
&& empty_op2
)
2043 zero
= gfc_get_int_expr (gfc_charlen_int_kind
, &e
->where
, 0);
2044 str
= empty_op1
? op2
: op1
;
2046 fcn
= get_len_trim_call (str
, gfc_charlen_int_kind
);
2050 gfc_free_expr (op1
);
2052 gfc_free_expr (op2
);
2056 e
->value
.op
.op1
= fcn
;
2057 e
->value
.op
.op2
= zero
;
2062 /* Don't compare REAL or COMPLEX expressions when honoring NaNs. */
2064 if (flag_finite_math_only
2065 || (op1
->ts
.type
!= BT_REAL
&& op2
->ts
.type
!= BT_REAL
2066 && op1
->ts
.type
!= BT_COMPLEX
&& op2
->ts
.type
!= BT_COMPLEX
))
2068 eq
= gfc_dep_compare_expr (op1
, op2
);
2071 /* Replace A // B < A // C with B < C, and A // B < C // B
2073 if (op1
->ts
.type
== BT_CHARACTER
&& op2
->ts
.type
== BT_CHARACTER
2074 && op1
->expr_type
== EXPR_OP
2075 && op1
->value
.op
.op
== INTRINSIC_CONCAT
2076 && op2
->expr_type
== EXPR_OP
2077 && op2
->value
.op
.op
== INTRINSIC_CONCAT
)
2079 gfc_expr
*op1_left
= op1
->value
.op
.op1
;
2080 gfc_expr
*op2_left
= op2
->value
.op
.op1
;
2081 gfc_expr
*op1_right
= op1
->value
.op
.op2
;
2082 gfc_expr
*op2_right
= op2
->value
.op
.op2
;
2084 if (gfc_dep_compare_expr (op1_left
, op2_left
) == 0)
2086 /* Watch out for 'A ' // x vs. 'A' // x. */
2088 if (op1_left
->expr_type
== EXPR_CONSTANT
2089 && op2_left
->expr_type
== EXPR_CONSTANT
2090 && op1_left
->value
.character
.length
2091 != op2_left
->value
.character
.length
)
2099 firstarg
->expr
= op1_right
;
2100 secondarg
->expr
= op2_right
;
2104 e
->value
.op
.op1
= op1_right
;
2105 e
->value
.op
.op2
= op2_right
;
2107 optimize_comparison (e
, op
);
2111 if (gfc_dep_compare_expr (op1_right
, op2_right
) == 0)
2117 firstarg
->expr
= op1_left
;
2118 secondarg
->expr
= op2_left
;
2122 e
->value
.op
.op1
= op1_left
;
2123 e
->value
.op
.op2
= op2_left
;
2126 optimize_comparison (e
, op
);
2133 /* eq can only be -1, 0 or 1 at this point. */
2161 gfc_internal_error ("illegal OP in optimize_comparison");
2165 /* Replace the expression by a constant expression. The typespec
2166 and where remains the way it is. */
2169 e
->expr_type
= EXPR_CONSTANT
;
2170 e
->value
.logical
= result
;
2178 /* Optimize a trim function by replacing it with an equivalent substring
2179 involving a call to len_trim. This only works for expressions where
2180 variables are trimmed. Return true if anything was modified. */
2183 optimize_trim (gfc_expr
*e
)
2188 gfc_ref
**rr
= NULL
;
2190 /* Don't do this optimization within an argument list, because
2191 otherwise aliasing issues may occur. */
2193 if (count_arglist
!= 1)
2196 if (e
->ts
.type
!= BT_CHARACTER
|| e
->expr_type
!= EXPR_FUNCTION
2197 || e
->value
.function
.isym
== NULL
2198 || e
->value
.function
.isym
->id
!= GFC_ISYM_TRIM
)
2201 a
= e
->value
.function
.actual
->expr
;
2203 if (a
->expr_type
!= EXPR_VARIABLE
)
2206 /* This would pessimize the idiom a = trim(a) for reallocatable strings. */
2208 if (a
->symtree
->n
.sym
->attr
.allocatable
)
2211 /* Follow all references to find the correct place to put the newly
2212 created reference. FIXME: Also handle substring references and
2213 array references. Array references cause strange regressions at
2218 for (rr
= &(a
->ref
); *rr
; rr
= &((*rr
)->next
))
2220 if ((*rr
)->type
== REF_SUBSTRING
|| (*rr
)->type
== REF_ARRAY
)
2225 strip_function_call (e
);
2230 /* Create the reference. */
2232 ref
= gfc_get_ref ();
2233 ref
->type
= REF_SUBSTRING
;
2235 /* Set the start of the reference. */
2237 ref
->u
.ss
.start
= gfc_get_int_expr (gfc_charlen_int_kind
, NULL
, 1);
2239 /* Build the function call to len_trim(x, gfc_default_integer_kind). */
2241 fcn
= get_len_trim_call (gfc_copy_expr (e
), gfc_charlen_int_kind
);
2243 /* Set the end of the reference to the call to len_trim. */
2245 ref
->u
.ss
.end
= fcn
;
2246 gcc_assert (rr
!= NULL
&& *rr
== NULL
);
2251 /* Optimize minloc(b), where b is rank 1 array, into
2252 (/ minloc(b, dim=1) /), and similarly for maxloc,
2253 as the latter forms are expanded inline. */
2256 optimize_minmaxloc (gfc_expr
**e
)
2259 gfc_actual_arglist
*a
;
2263 || fn
->value
.function
.actual
== NULL
2264 || fn
->value
.function
.actual
->expr
== NULL
2265 || fn
->value
.function
.actual
->expr
->rank
!= 1)
2268 *e
= gfc_get_array_expr (fn
->ts
.type
, fn
->ts
.kind
, &fn
->where
);
2269 (*e
)->shape
= fn
->shape
;
2272 gfc_constructor_append_expr (&(*e
)->value
.constructor
, fn
, &fn
->where
);
2274 name
= XALLOCAVEC (char, strlen (fn
->value
.function
.name
) + 1);
2275 strcpy (name
, fn
->value
.function
.name
);
2276 p
= strstr (name
, "loc0");
2278 fn
->value
.function
.name
= gfc_get_string ("%s", name
);
2279 if (fn
->value
.function
.actual
->next
)
2281 a
= fn
->value
.function
.actual
->next
;
2282 gcc_assert (a
->expr
== NULL
);
2286 a
= gfc_get_actual_arglist ();
2287 fn
->value
.function
.actual
->next
= a
;
2289 a
->expr
= gfc_get_constant_expr (BT_INTEGER
, gfc_default_integer_kind
,
2291 mpz_set_ui (a
->expr
->value
.integer
, 1);
2294 /* Callback function for code checking that we do not pass a DO variable to an
2295 INTENT(OUT) or INTENT(INOUT) dummy variable. */
2298 doloop_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
2299 void *data ATTRIBUTE_UNUSED
)
2303 gfc_formal_arglist
*f
;
2304 gfc_actual_arglist
*a
;
2311 /* If the doloop_list grew, we have to truncate it here. */
2313 if ((unsigned) doloop_level
< doloop_list
.length())
2314 doloop_list
.truncate (doloop_level
);
2321 if (co
->ext
.iterator
&& co
->ext
.iterator
->var
)
2326 loop
.branch_level
= if_level
+ select_level
;
2327 loop
.seen_goto
= false;
2328 doloop_list
.safe_push (loop
);
2331 /* If anything could transfer control away from a suspicious
2332 subscript, make sure to set seen_goto in the current DO loop
2337 case EXEC_ERROR_STOP
:
2343 if (co
->ext
.open
->err
)
2348 if (co
->ext
.close
->err
)
2352 case EXEC_BACKSPACE
:
2357 if (co
->ext
.filepos
->err
)
2362 if (co
->ext
.filepos
->err
)
2368 if (co
->ext
.dt
->err
|| co
->ext
.dt
->end
|| co
->ext
.dt
->eor
)
2373 if (co
->ext
.wait
->err
|| co
->ext
.wait
->end
|| co
->ext
.wait
->eor
)
2374 loop
.seen_goto
= true;
2379 if (co
->resolved_sym
== NULL
)
2382 f
= gfc_sym_get_dummy_args (co
->resolved_sym
);
2384 /* Withot a formal arglist, there is only unknown INTENT,
2385 which we don't check for. */
2393 FOR_EACH_VEC_ELT (doloop_list
, i
, lp
)
2401 do_sym
= cl
->ext
.iterator
->var
->symtree
->n
.sym
;
2403 if (a
->expr
&& a
->expr
->symtree
2404 && a
->expr
->symtree
->n
.sym
== do_sym
)
2406 if (f
->sym
->attr
.intent
== INTENT_OUT
)
2407 gfc_error_now ("Variable %qs at %L set to undefined "
2408 "value inside loop beginning at %L as "
2409 "INTENT(OUT) argument to subroutine %qs",
2410 do_sym
->name
, &a
->expr
->where
,
2411 &(doloop_list
[i
].c
->loc
),
2412 co
->symtree
->n
.sym
->name
);
2413 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
2414 gfc_error_now ("Variable %qs at %L not definable inside "
2415 "loop beginning at %L as INTENT(INOUT) "
2416 "argument to subroutine %qs",
2417 do_sym
->name
, &a
->expr
->where
,
2418 &(doloop_list
[i
].c
->loc
),
2419 co
->symtree
->n
.sym
->name
);
2430 if (seen_goto
&& doloop_level
> 0)
2431 doloop_list
[doloop_level
-1].seen_goto
= true;
2436 /* Callback function to warn about different things within DO loops. */
2439 do_function (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
2440 void *data ATTRIBUTE_UNUSED
)
2444 if (doloop_list
.length () == 0)
2447 if ((*e
)->expr_type
== EXPR_FUNCTION
)
2450 last
= &doloop_list
.last();
2451 if (last
->seen_goto
&& !warn_do_subscript
)
2454 if ((*e
)->expr_type
== EXPR_VARIABLE
)
2466 /* Callback function - if the expression is the variable in data->sym,
2467 replace it with a constant from data->val. */
2470 callback_insert_index (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
2477 if (ex
->expr_type
!= EXPR_VARIABLE
)
2480 d
= (insert_index_t
*) data
;
2481 if (ex
->symtree
->n
.sym
!= d
->sym
)
2484 n
= gfc_get_constant_expr (BT_INTEGER
, ex
->ts
.kind
, &ex
->where
);
2485 mpz_set (n
->value
.integer
, d
->val
);
2492 /* In the expression e, replace occurrences of the variable sym with
2493 val. If this results in a constant expression, return true and
2494 return the value in ret. Return false if the expression already
2495 is a constant. Caller has to clear ret in that case. */
2498 insert_index (gfc_expr
*e
, gfc_symbol
*sym
, mpz_t val
, mpz_t ret
)
2501 insert_index_t data
;
2504 if (e
->expr_type
== EXPR_CONSTANT
)
2507 n
= gfc_copy_expr (e
);
2509 mpz_init_set (data
.val
, val
);
2510 gfc_expr_walker (&n
, callback_insert_index
, (void *) &data
);
2511 gfc_simplify_expr (n
, 0);
2513 if (n
->expr_type
== EXPR_CONSTANT
)
2516 mpz_init_set (ret
, n
->value
.integer
);
2521 mpz_clear (data
.val
);
2527 /* Check array subscripts for possible out-of-bounds accesses in DO
2528 loops with constant bounds. */
2531 do_subscript (gfc_expr
**e
)
2541 /* Constants are already checked. */
2542 if (v
->expr_type
== EXPR_CONSTANT
)
2545 /* Wrong warnings will be generated in an associate list. */
2549 for (ref
= v
->ref
; ref
; ref
= ref
->next
)
2551 if (ref
->type
== REF_ARRAY
&& ref
->u
.ar
.type
== AR_ELEMENT
)
2554 FOR_EACH_VEC_ELT (doloop_list
, j
, lp
)
2557 mpz_t do_start
, do_step
, do_end
;
2558 bool have_do_start
, have_do_end
;
2559 bool error_not_proven
;
2566 /* If we are within a branch, or a goto or equivalent
2567 was seen in the DO loop before, then we cannot prove that
2568 this expression is actually evaluated. Don't do anything
2569 unless we want to see it all. */
2570 error_not_proven
= lp
->seen_goto
2571 || lp
->branch_level
< if_level
+ select_level
;
2573 if (error_not_proven
&& !warn_do_subscript
)
2576 if (error_not_proven
)
2577 warn
= OPT_Wdo_subscript
;
2581 do_sym
= dl
->ext
.iterator
->var
->symtree
->n
.sym
;
2582 if (do_sym
->ts
.type
!= BT_INTEGER
)
2585 /* If we do not know about the stepsize, the loop may be zero trip.
2586 Do not warn in this case. */
2588 if (dl
->ext
.iterator
->step
->expr_type
== EXPR_CONSTANT
)
2589 mpz_init_set (do_step
, dl
->ext
.iterator
->step
->value
.integer
);
2593 if (dl
->ext
.iterator
->start
->expr_type
== EXPR_CONSTANT
)
2595 have_do_start
= true;
2596 mpz_init_set (do_start
, dl
->ext
.iterator
->start
->value
.integer
);
2599 have_do_start
= false;
2602 if (dl
->ext
.iterator
->end
->expr_type
== EXPR_CONSTANT
)
2605 mpz_init_set (do_end
, dl
->ext
.iterator
->end
->value
.integer
);
2608 have_do_end
= false;
2610 if (!have_do_start
&& !have_do_end
)
2613 /* May have to correct the end value if the step does not equal
2615 if (have_do_start
&& have_do_end
&& mpz_cmp_ui (do_step
, 1) != 0)
2621 mpz_sub (diff
, do_end
, do_start
);
2622 mpz_tdiv_r (rem
, diff
, do_step
);
2623 mpz_sub (do_end
, do_end
, rem
);
2628 for (i
= 0; i
< ar
->dimen
; i
++)
2631 if (ar
->dimen_type
[i
] == DIMEN_ELEMENT
&& have_do_start
2632 && insert_index (ar
->start
[i
], do_sym
, do_start
, val
))
2634 if (ar
->as
->lower
[i
]
2635 && ar
->as
->lower
[i
]->expr_type
== EXPR_CONSTANT
2636 && mpz_cmp (val
, ar
->as
->lower
[i
]->value
.integer
) < 0)
2637 gfc_warning (warn
, "Array reference at %L out of bounds "
2638 "(%ld < %ld) in loop beginning at %L",
2639 &ar
->start
[i
]->where
, mpz_get_si (val
),
2640 mpz_get_si (ar
->as
->lower
[i
]->value
.integer
),
2641 &doloop_list
[j
].c
->loc
);
2643 if (ar
->as
->upper
[i
]
2644 && ar
->as
->upper
[i
]->expr_type
== EXPR_CONSTANT
2645 && mpz_cmp (val
, ar
->as
->upper
[i
]->value
.integer
) > 0)
2646 gfc_warning (warn
, "Array reference at %L out of bounds "
2647 "(%ld > %ld) in loop beginning at %L",
2648 &ar
->start
[i
]->where
, mpz_get_si (val
),
2649 mpz_get_si (ar
->as
->upper
[i
]->value
.integer
),
2650 &doloop_list
[j
].c
->loc
);
2655 if (ar
->dimen_type
[i
] == DIMEN_ELEMENT
&& have_do_end
2656 && insert_index (ar
->start
[i
], do_sym
, do_end
, val
))
2658 if (ar
->as
->lower
[i
]
2659 && ar
->as
->lower
[i
]->expr_type
== EXPR_CONSTANT
2660 && mpz_cmp (val
, ar
->as
->lower
[i
]->value
.integer
) < 0)
2661 gfc_warning (warn
, "Array reference at %L out of bounds "
2662 "(%ld < %ld) in loop beginning at %L",
2663 &ar
->start
[i
]->where
, mpz_get_si (val
),
2664 mpz_get_si (ar
->as
->lower
[i
]->value
.integer
),
2665 &doloop_list
[j
].c
->loc
);
2667 if (ar
->as
->upper
[i
]
2668 && ar
->as
->upper
[i
]->expr_type
== EXPR_CONSTANT
2669 && mpz_cmp (val
, ar
->as
->upper
[i
]->value
.integer
) > 0)
2670 gfc_warning (warn
, "Array reference at %L out of bounds "
2671 "(%ld > %ld) in loop beginning at %L",
2672 &ar
->start
[i
]->where
, mpz_get_si (val
),
2673 mpz_get_si (ar
->as
->upper
[i
]->value
.integer
),
2674 &doloop_list
[j
].c
->loc
);
2684 /* Function for functions checking that we do not pass a DO variable
2685 to an INTENT(OUT) or INTENT(INOUT) dummy variable. */
2688 do_intent (gfc_expr
**e
)
2690 gfc_formal_arglist
*f
;
2691 gfc_actual_arglist
*a
;
2698 if (expr
->expr_type
!= EXPR_FUNCTION
)
2701 /* Intrinsic functions don't modify their arguments. */
2703 if (expr
->value
.function
.isym
)
2706 f
= gfc_sym_get_dummy_args (expr
->symtree
->n
.sym
);
2708 /* Without a formal arglist, there is only unknown INTENT,
2709 which we don't check for. */
2713 a
= expr
->value
.function
.actual
;
2717 FOR_EACH_VEC_ELT (doloop_list
, i
, lp
)
2724 do_sym
= dl
->ext
.iterator
->var
->symtree
->n
.sym
;
2726 if (a
->expr
&& a
->expr
->symtree
2727 && a
->expr
->symtree
->n
.sym
== do_sym
)
2729 if (f
->sym
->attr
.intent
== INTENT_OUT
)
2730 gfc_error_now ("Variable %qs at %L set to undefined value "
2731 "inside loop beginning at %L as INTENT(OUT) "
2732 "argument to function %qs", do_sym
->name
,
2733 &a
->expr
->where
, &doloop_list
[i
].c
->loc
,
2734 expr
->symtree
->n
.sym
->name
);
2735 else if (f
->sym
->attr
.intent
== INTENT_INOUT
)
2736 gfc_error_now ("Variable %qs at %L not definable inside loop"
2737 " beginning at %L as INTENT(INOUT) argument to"
2738 " function %qs", do_sym
->name
,
2739 &a
->expr
->where
, &doloop_list
[i
].c
->loc
,
2740 expr
->symtree
->n
.sym
->name
);
2751 doloop_warn (gfc_namespace
*ns
)
2753 gfc_code_walker (&ns
->code
, doloop_code
, do_function
, NULL
);
2756 /* This selction deals with inlining calls to MATMUL. */
2758 /* Replace calls to matmul outside of straight assignments with a temporary
2759 variable so that later inlining will work. */
2762 matmul_to_var_expr (gfc_expr
**ep
, int *walk_subtrees ATTRIBUTE_UNUSED
,
2766 bool *found
= (bool *) data
;
2770 if (e
->expr_type
!= EXPR_FUNCTION
2771 || e
->value
.function
.isym
== NULL
2772 || e
->value
.function
.isym
->id
!= GFC_ISYM_MATMUL
)
2775 if (forall_level
> 0 || iterator_level
> 0 || in_omp_workshare
2776 || in_where
|| in_assoc_list
)
2779 /* Check if this is already in the form c = matmul(a,b). */
2781 if ((*current_code
)->expr2
== e
)
2784 n
= create_var (e
, "matmul");
2786 /* If create_var is unable to create a variable (for example if
2787 -fno-realloc-lhs is in force with a variable that does not have bounds
2788 known at compile-time), just return. */
2798 /* Set current_code and associated variables so that matmul_to_var_expr can
2802 matmul_to_var_code (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
2803 void *data ATTRIBUTE_UNUSED
)
2805 if (current_code
!= c
)
2808 inserted_block
= NULL
;
2809 changed_statement
= NULL
;
2816 /* Take a statement of the shape c = matmul(a,b) and create temporaries
2817 for a and b if there is a dependency between the arguments and the
2818 result variable or if a or b are the result of calculations that cannot
2819 be handled by the inliner. */
2822 matmul_temp_args (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
2823 void *data ATTRIBUTE_UNUSED
)
2825 gfc_expr
*expr1
, *expr2
;
2827 gfc_actual_arglist
*a
, *b
;
2829 gfc_expr
*matrix_a
, *matrix_b
;
2830 bool conjg_a
, conjg_b
, transpose_a
, transpose_b
;
2834 if (co
->op
!= EXEC_ASSIGN
)
2837 if (forall_level
> 0 || iterator_level
> 0 || in_omp_workshare
2841 /* This has some duplication with inline_matmul_assign. This
2842 is because the creation of temporary variables could still fail,
2843 and inline_matmul_assign still needs to be able to handle these
2848 if (expr2
->expr_type
!= EXPR_FUNCTION
2849 || expr2
->value
.function
.isym
== NULL
2850 || expr2
->value
.function
.isym
->id
!= GFC_ISYM_MATMUL
)
2854 a
= expr2
->value
.function
.actual
;
2855 matrix_a
= check_conjg_transpose_variable (a
->expr
, &conjg_a
, &transpose_a
);
2856 if (matrix_a
!= NULL
)
2858 if (matrix_a
->expr_type
== EXPR_VARIABLE
2859 && (gfc_check_dependency (matrix_a
, expr1
, true)
2860 || has_dimen_vector_ref (matrix_a
)))
2868 matrix_b
= check_conjg_transpose_variable (b
->expr
, &conjg_b
, &transpose_b
);
2869 if (matrix_b
!= NULL
)
2871 if (matrix_b
->expr_type
== EXPR_VARIABLE
2872 && (gfc_check_dependency (matrix_b
, expr1
, true)
2873 || has_dimen_vector_ref (matrix_b
)))
2879 if (!a_tmp
&& !b_tmp
)
2883 inserted_block
= NULL
;
2884 changed_statement
= NULL
;
2888 at
= create_var (a
->expr
,"mma");
2895 bt
= create_var (b
->expr
,"mmb");
2902 /* Auxiliary function to build and simplify an array inquiry function.
2903 dim is zero-based. */
2906 get_array_inq_function (gfc_isym_id id
, gfc_expr
*e
, int dim
)
2909 gfc_expr
*dim_arg
, *kind
;
2915 case GFC_ISYM_LBOUND
:
2916 name
= "_gfortran_lbound";
2919 case GFC_ISYM_UBOUND
:
2920 name
= "_gfortran_ubound";
2924 name
= "_gfortran_size";
2931 dim_arg
= gfc_get_int_expr (gfc_default_integer_kind
, &e
->where
, dim
);
2932 kind
= gfc_get_int_expr (gfc_default_integer_kind
, &e
->where
,
2933 gfc_index_integer_kind
);
2935 ec
= gfc_copy_expr (e
);
2936 fcn
= gfc_build_intrinsic_call (current_ns
, id
, name
, e
->where
, 3,
2938 gfc_simplify_expr (fcn
, 0);
2942 /* Builds a logical expression. */
2945 build_logical_expr (gfc_intrinsic_op op
, gfc_expr
*e1
, gfc_expr
*e2
)
2950 ts
.type
= BT_LOGICAL
;
2951 ts
.kind
= gfc_default_logical_kind
;
2952 res
= gfc_get_expr ();
2953 res
->where
= e1
->where
;
2954 res
->expr_type
= EXPR_OP
;
2955 res
->value
.op
.op
= op
;
2956 res
->value
.op
.op1
= e1
;
2957 res
->value
.op
.op2
= e2
;
2964 /* Return an operation of one two gfc_expr (one if e2 is NULL). This assumes
2965 compatible typespecs. */
2968 get_operand (gfc_intrinsic_op op
, gfc_expr
*e1
, gfc_expr
*e2
)
2972 res
= gfc_get_expr ();
2974 res
->where
= e1
->where
;
2975 res
->expr_type
= EXPR_OP
;
2976 res
->value
.op
.op
= op
;
2977 res
->value
.op
.op1
= e1
;
2978 res
->value
.op
.op2
= e2
;
2979 gfc_simplify_expr (res
, 0);
2983 /* Generate the IF statement for a runtime check if we want to do inlining or
2984 not - putting in the code for both branches and putting it into the syntax
2985 tree is the caller's responsibility. For fixed array sizes, this should be
2986 removed by DCE. Only called for rank-two matrices A and B. */
2989 inline_limit_check (gfc_expr
*a
, gfc_expr
*b
, enum matrix_case m_case
)
2991 gfc_expr
*inline_limit
;
2992 gfc_code
*if_1
, *if_2
, *else_2
;
2993 gfc_expr
*b2
, *a2
, *a1
, *m1
, *m2
;
2997 gcc_assert (m_case
== A2B2
|| m_case
== A2B2T
|| m_case
== A2TB2
);
2999 /* Calculation is done in real to avoid integer overflow. */
3001 inline_limit
= gfc_get_constant_expr (BT_REAL
, gfc_default_real_kind
,
3003 mpfr_set_si (inline_limit
->value
.real
, flag_inline_matmul_limit
,
3005 mpfr_pow_ui (inline_limit
->value
.real
, inline_limit
->value
.real
, 3,
3008 a1
= get_array_inq_function (GFC_ISYM_SIZE
, a
, 1);
3009 a2
= get_array_inq_function (GFC_ISYM_SIZE
, a
, 2);
3010 b2
= get_array_inq_function (GFC_ISYM_SIZE
, b
, 2);
3014 ts
.kind
= gfc_default_real_kind
;
3015 gfc_convert_type_warn (a1
, &ts
, 2, 0);
3016 gfc_convert_type_warn (a2
, &ts
, 2, 0);
3017 gfc_convert_type_warn (b2
, &ts
, 2, 0);
3019 m1
= get_operand (INTRINSIC_TIMES
, a1
, a2
);
3020 m2
= get_operand (INTRINSIC_TIMES
, m1
, b2
);
3022 cond
= build_logical_expr (INTRINSIC_LE
, m2
, inline_limit
);
3023 gfc_simplify_expr (cond
, 0);
3025 else_2
= XCNEW (gfc_code
);
3026 else_2
->op
= EXEC_IF
;
3027 else_2
->loc
= a
->where
;
3029 if_2
= XCNEW (gfc_code
);
3032 if_2
->loc
= a
->where
;
3033 if_2
->block
= else_2
;
3035 if_1
= XCNEW (gfc_code
);
3038 if_1
->loc
= a
->where
;
3044 /* Insert code to issue a runtime error if the expressions are not equal. */
3047 runtime_error_ne (gfc_expr
*e1
, gfc_expr
*e2
, const char *msg
)
3050 gfc_code
*if_1
, *if_2
;
3052 gfc_actual_arglist
*a1
, *a2
, *a3
;
3054 gcc_assert (e1
->where
.lb
);
3055 /* Build the call to runtime_error. */
3056 c
= XCNEW (gfc_code
);
3060 /* Get a null-terminated message string. */
3062 a1
= gfc_get_actual_arglist ();
3063 a1
->expr
= gfc_get_character_expr (gfc_default_character_kind
, &e1
->where
,
3064 msg
, strlen(msg
)+1);
3067 /* Pass the value of the first expression. */
3068 a2
= gfc_get_actual_arglist ();
3069 a2
->expr
= gfc_copy_expr (e1
);
3072 /* Pass the value of the second expression. */
3073 a3
= gfc_get_actual_arglist ();
3074 a3
->expr
= gfc_copy_expr (e2
);
3077 gfc_check_fe_runtime_error (c
->ext
.actual
);
3078 gfc_resolve_fe_runtime_error (c
);
3080 if_2
= XCNEW (gfc_code
);
3082 if_2
->loc
= e1
->where
;
3085 if_1
= XCNEW (gfc_code
);
3088 if_1
->loc
= e1
->where
;
3090 cond
= build_logical_expr (INTRINSIC_NE
, e1
, e2
);
3091 gfc_simplify_expr (cond
, 0);
3097 /* Handle matrix reallocation. Caller is responsible to insert into
3100 For the two-dimensional case, build
3102 if (allocated(c)) then
3103 if (size(c,1) /= size(a,1) .or. size(c,2) /= size(b,2)) then
3105 allocate (c(size(a,1), size(b,2)))
3108 allocate (c(size(a,1),size(b,2)))
3111 and for the other cases correspondingly.
3115 matmul_lhs_realloc (gfc_expr
*c
, gfc_expr
*a
, gfc_expr
*b
,
3116 enum matrix_case m_case
)
3119 gfc_expr
*allocated
, *alloc_expr
;
3120 gfc_code
*if_alloc_1
, *if_alloc_2
, *if_size_1
, *if_size_2
;
3121 gfc_code
*else_alloc
;
3122 gfc_code
*deallocate
, *allocate1
, *allocate_else
;
3124 gfc_expr
*cond
, *ne1
, *ne2
;
3126 if (warn_realloc_lhs
)
3127 gfc_warning (OPT_Wrealloc_lhs
,
3128 "Code for reallocating the allocatable array at %L will "
3129 "be added", &c
->where
);
3131 alloc_expr
= gfc_copy_expr (c
);
3133 ar
= gfc_find_array_ref (alloc_expr
);
3134 gcc_assert (ar
&& ar
->type
== AR_FULL
);
3136 /* c comes in as a full ref. Change it into a copy and make it into an
3137 element ref so it has the right form for for ALLOCATE. In the same
3138 switch statement, also generate the size comparison for the secod IF
3141 ar
->type
= AR_ELEMENT
;
3146 ar
->start
[0] = get_array_inq_function (GFC_ISYM_SIZE
, a
, 1);
3147 ar
->start
[1] = get_array_inq_function (GFC_ISYM_SIZE
, b
, 2);
3148 ne1
= build_logical_expr (INTRINSIC_NE
,
3149 get_array_inq_function (GFC_ISYM_SIZE
, c
, 1),
3150 get_array_inq_function (GFC_ISYM_SIZE
, a
, 1));
3151 ne2
= build_logical_expr (INTRINSIC_NE
,
3152 get_array_inq_function (GFC_ISYM_SIZE
, c
, 2),
3153 get_array_inq_function (GFC_ISYM_SIZE
, b
, 2));
3154 cond
= build_logical_expr (INTRINSIC_OR
, ne1
, ne2
);
3158 ar
->start
[0] = get_array_inq_function (GFC_ISYM_SIZE
, a
, 1);
3159 ar
->start
[1] = get_array_inq_function (GFC_ISYM_SIZE
, b
, 1);
3161 ne1
= build_logical_expr (INTRINSIC_NE
,
3162 get_array_inq_function (GFC_ISYM_SIZE
, c
, 1),
3163 get_array_inq_function (GFC_ISYM_SIZE
, a
, 1));
3164 ne2
= build_logical_expr (INTRINSIC_NE
,
3165 get_array_inq_function (GFC_ISYM_SIZE
, c
, 2),
3166 get_array_inq_function (GFC_ISYM_SIZE
, b
, 1));
3167 cond
= build_logical_expr (INTRINSIC_OR
, ne1
, ne2
);
3172 ar
->start
[0] = get_array_inq_function (GFC_ISYM_SIZE
, a
, 2);
3173 ar
->start
[1] = get_array_inq_function (GFC_ISYM_SIZE
, b
, 2);
3175 ne1
= build_logical_expr (INTRINSIC_NE
,
3176 get_array_inq_function (GFC_ISYM_SIZE
, c
, 1),
3177 get_array_inq_function (GFC_ISYM_SIZE
, a
, 2));
3178 ne2
= build_logical_expr (INTRINSIC_NE
,
3179 get_array_inq_function (GFC_ISYM_SIZE
, c
, 2),
3180 get_array_inq_function (GFC_ISYM_SIZE
, b
, 2));
3181 cond
= build_logical_expr (INTRINSIC_OR
, ne1
, ne2
);
3185 ar
->start
[0] = get_array_inq_function (GFC_ISYM_SIZE
, a
, 1);
3186 cond
= build_logical_expr (INTRINSIC_NE
,
3187 get_array_inq_function (GFC_ISYM_SIZE
, c
, 1),
3188 get_array_inq_function (GFC_ISYM_SIZE
, a
, 2));
3192 ar
->start
[0] = get_array_inq_function (GFC_ISYM_SIZE
, b
, 2);
3193 cond
= build_logical_expr (INTRINSIC_NE
,
3194 get_array_inq_function (GFC_ISYM_SIZE
, c
, 1),
3195 get_array_inq_function (GFC_ISYM_SIZE
, b
, 2));
3203 gfc_simplify_expr (cond
, 0);
3205 /* We need two identical allocate statements in two
3206 branches of the IF statement. */
3208 allocate1
= XCNEW (gfc_code
);
3209 allocate1
->op
= EXEC_ALLOCATE
;
3210 allocate1
->ext
.alloc
.list
= gfc_get_alloc ();
3211 allocate1
->loc
= c
->where
;
3212 allocate1
->ext
.alloc
.list
->expr
= gfc_copy_expr (alloc_expr
);
3214 allocate_else
= XCNEW (gfc_code
);
3215 allocate_else
->op
= EXEC_ALLOCATE
;
3216 allocate_else
->ext
.alloc
.list
= gfc_get_alloc ();
3217 allocate_else
->loc
= c
->where
;
3218 allocate_else
->ext
.alloc
.list
->expr
= alloc_expr
;
3220 allocated
= gfc_build_intrinsic_call (current_ns
, GFC_ISYM_ALLOCATED
,
3221 "_gfortran_allocated", c
->where
,
3222 1, gfc_copy_expr (c
));
3224 deallocate
= XCNEW (gfc_code
);
3225 deallocate
->op
= EXEC_DEALLOCATE
;
3226 deallocate
->ext
.alloc
.list
= gfc_get_alloc ();
3227 deallocate
->ext
.alloc
.list
->expr
= gfc_copy_expr (c
);
3228 deallocate
->next
= allocate1
;
3229 deallocate
->loc
= c
->where
;
3231 if_size_2
= XCNEW (gfc_code
);
3232 if_size_2
->op
= EXEC_IF
;
3233 if_size_2
->expr1
= cond
;
3234 if_size_2
->loc
= c
->where
;
3235 if_size_2
->next
= deallocate
;
3237 if_size_1
= XCNEW (gfc_code
);
3238 if_size_1
->op
= EXEC_IF
;
3239 if_size_1
->block
= if_size_2
;
3240 if_size_1
->loc
= c
->where
;
3242 else_alloc
= XCNEW (gfc_code
);
3243 else_alloc
->op
= EXEC_IF
;
3244 else_alloc
->loc
= c
->where
;
3245 else_alloc
->next
= allocate_else
;
3247 if_alloc_2
= XCNEW (gfc_code
);
3248 if_alloc_2
->op
= EXEC_IF
;
3249 if_alloc_2
->expr1
= allocated
;
3250 if_alloc_2
->loc
= c
->where
;
3251 if_alloc_2
->next
= if_size_1
;
3252 if_alloc_2
->block
= else_alloc
;
3254 if_alloc_1
= XCNEW (gfc_code
);
3255 if_alloc_1
->op
= EXEC_IF
;
3256 if_alloc_1
->block
= if_alloc_2
;
3257 if_alloc_1
->loc
= c
->where
;
3262 /* Callback function for has_function_or_op. */
3265 is_function_or_op (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
3266 void *data ATTRIBUTE_UNUSED
)
3271 return (*e
)->expr_type
== EXPR_FUNCTION
3272 || (*e
)->expr_type
== EXPR_OP
;
3275 /* Returns true if the expression contains a function. */
3278 has_function_or_op (gfc_expr
**e
)
3283 return gfc_expr_walker (e
, is_function_or_op
, NULL
);
3286 /* Freeze (assign to a temporary variable) a single expression. */
3289 freeze_expr (gfc_expr
**ep
)
3292 if (has_function_or_op (ep
))
3294 ne
= create_var (*ep
, "freeze");
3299 /* Go through an expression's references and assign them to temporary
3300 variables if they contain functions. This is usually done prior to
3301 front-end scalarization to avoid multiple invocations of functions. */
3304 freeze_references (gfc_expr
*e
)
3310 for (r
=e
->ref
; r
; r
=r
->next
)
3312 if (r
->type
== REF_SUBSTRING
)
3314 if (r
->u
.ss
.start
!= NULL
)
3315 freeze_expr (&r
->u
.ss
.start
);
3317 if (r
->u
.ss
.end
!= NULL
)
3318 freeze_expr (&r
->u
.ss
.end
);
3320 else if (r
->type
== REF_ARRAY
)
3329 for (i
=0; i
<ar
->dimen
; i
++)
3331 if (ar
->dimen_type
[i
] == DIMEN_RANGE
)
3333 freeze_expr (&ar
->start
[i
]);
3334 freeze_expr (&ar
->end
[i
]);
3335 freeze_expr (&ar
->stride
[i
]);
3337 else if (ar
->dimen_type
[i
] == DIMEN_ELEMENT
)
3339 freeze_expr (&ar
->start
[i
]);
3345 for (i
=0; i
<ar
->dimen
; i
++)
3346 freeze_expr (&ar
->start
[i
]);
3356 /* Convert to gfc_index_integer_kind if needed, just do a copy otherwise. */
3359 convert_to_index_kind (gfc_expr
*e
)
3363 gcc_assert (e
!= NULL
);
3365 res
= gfc_copy_expr (e
);
3367 gcc_assert (e
->ts
.type
== BT_INTEGER
);
3369 if (res
->ts
.kind
!= gfc_index_integer_kind
)
3373 ts
.type
= BT_INTEGER
;
3374 ts
.kind
= gfc_index_integer_kind
;
3376 gfc_convert_type_warn (e
, &ts
, 2, 0);
3382 /* Function to create a DO loop including creation of the
3383 iteration variable. gfc_expr are copied.*/
3386 create_do_loop (gfc_expr
*start
, gfc_expr
*end
, gfc_expr
*step
, locus
*where
,
3387 gfc_namespace
*ns
, char *vname
)
3390 char name
[GFC_MAX_SYMBOL_LEN
+1];
3391 gfc_symtree
*symtree
;
3396 /* Create an expression for the iteration variable. */
3398 sprintf (name
, "__var_%d_do_%s", var_num
++, vname
);
3400 sprintf (name
, "__var_%d_do", var_num
++);
3403 if (gfc_get_sym_tree (name
, ns
, &symtree
, false) != 0)
3406 /* Create the loop variable. */
3408 symbol
= symtree
->n
.sym
;
3409 symbol
->ts
.type
= BT_INTEGER
;
3410 symbol
->ts
.kind
= gfc_index_integer_kind
;
3411 symbol
->attr
.flavor
= FL_VARIABLE
;
3412 symbol
->attr
.referenced
= 1;
3413 symbol
->attr
.dimension
= 0;
3414 symbol
->attr
.fe_temp
= 1;
3415 gfc_commit_symbol (symbol
);
3417 i
= gfc_get_expr ();
3418 i
->expr_type
= EXPR_VARIABLE
;
3422 i
->symtree
= symtree
;
3424 /* ... and the nested DO statements. */
3425 n
= XCNEW (gfc_code
);
3428 n
->ext
.iterator
= gfc_get_iterator ();
3429 n
->ext
.iterator
->var
= i
;
3430 n
->ext
.iterator
->start
= convert_to_index_kind (start
);
3431 n
->ext
.iterator
->end
= convert_to_index_kind (end
);
3433 n
->ext
.iterator
->step
= convert_to_index_kind (step
);
3435 n
->ext
.iterator
->step
= gfc_get_int_expr (gfc_index_integer_kind
,
3438 n2
= XCNEW (gfc_code
);
3446 /* Get the upper bound of the DO loops for matmul along a dimension. This
3450 get_size_m1 (gfc_expr
*e
, int dimen
)
3455 if (gfc_array_dimen_size (e
, dimen
- 1, &size
))
3457 res
= gfc_get_constant_expr (BT_INTEGER
,
3458 gfc_index_integer_kind
, &e
->where
);
3459 mpz_sub_ui (res
->value
.integer
, size
, 1);
3464 res
= get_operand (INTRINSIC_MINUS
,
3465 get_array_inq_function (GFC_ISYM_SIZE
, e
, dimen
),
3466 gfc_get_int_expr (gfc_index_integer_kind
,
3468 gfc_simplify_expr (res
, 0);
3474 /* Function to return a scalarized expression. It is assumed that indices are
3475 zero based to make generation of DO loops easier. A zero as index will
3476 access the first element along a dimension. Single element references will
3477 be skipped. A NULL as an expression will be replaced by a full reference.
3478 This assumes that the index loops have gfc_index_integer_kind, and that all
3479 references have been frozen. */
3482 scalarized_expr (gfc_expr
*e_in
, gfc_expr
**index
, int count_index
)
3491 e
= gfc_copy_expr(e_in
);
3495 ar
= gfc_find_array_ref (e
);
3497 /* We scalarize count_index variables, reducing the rank by count_index. */
3499 e
->rank
= rank
- count_index
;
3501 was_fullref
= ar
->type
== AR_FULL
;
3504 ar
->type
= AR_ELEMENT
;
3506 ar
->type
= AR_SECTION
;
3508 /* Loop over the indices. For each index, create the expression
3509 index * stride + lbound(e, dim). */
3512 for (i
=0; i
< ar
->dimen
; i
++)
3514 if (was_fullref
|| ar
->dimen_type
[i
] == DIMEN_RANGE
)
3516 if (index
[i_index
] != NULL
)
3518 gfc_expr
*lbound
, *nindex
;
3521 loopvar
= gfc_copy_expr (index
[i_index
]);
3527 tmp
= gfc_copy_expr(ar
->stride
[i
]);
3528 if (tmp
->ts
.kind
!= gfc_index_integer_kind
)
3532 ts
.type
= BT_INTEGER
;
3533 ts
.kind
= gfc_index_integer_kind
;
3534 gfc_convert_type (tmp
, &ts
, 2);
3536 nindex
= get_operand (INTRINSIC_TIMES
, loopvar
, tmp
);
3541 /* Calculate the lower bound of the expression. */
3544 lbound
= gfc_copy_expr (ar
->start
[i
]);
3545 if (lbound
->ts
.kind
!= gfc_index_integer_kind
)
3549 ts
.type
= BT_INTEGER
;
3550 ts
.kind
= gfc_index_integer_kind
;
3551 gfc_convert_type (lbound
, &ts
, 2);
3560 lbound_e
= gfc_copy_expr (e_in
);
3562 for (ref
= lbound_e
->ref
; ref
; ref
= ref
->next
)
3563 if (ref
->type
== REF_ARRAY
3564 && (ref
->u
.ar
.type
== AR_FULL
3565 || ref
->u
.ar
.type
== AR_SECTION
))
3570 gfc_free_ref_list (ref
->next
);
3576 /* Look at full individual sections, like a(:). The first index
3577 is the lbound of a full ref. */
3584 /* For assumed size, we need to keep around the final
3585 reference in order not to get an error on resolution
3586 below, and we cannot use AR_FULL. */
3588 if (ar
->as
->type
== AS_ASSUMED_SIZE
)
3590 ar
->type
= AR_SECTION
;
3599 for (j
= 0; j
< to
; j
++)
3601 gfc_free_expr (ar
->start
[j
]);
3602 ar
->start
[j
] = NULL
;
3603 gfc_free_expr (ar
->end
[j
]);
3605 gfc_free_expr (ar
->stride
[j
]);
3606 ar
->stride
[j
] = NULL
;
3609 /* We have to get rid of the shape, if there is one. Do
3610 so by freeing it and calling gfc_resolve to rebuild
3611 it, if necessary. */
3613 if (lbound_e
->shape
)
3614 gfc_free_shape (&(lbound_e
->shape
), lbound_e
->rank
);
3616 lbound_e
->rank
= ar
->dimen
;
3617 gfc_resolve_expr (lbound_e
);
3619 lbound
= get_array_inq_function (GFC_ISYM_LBOUND
, lbound_e
,
3621 gfc_free_expr (lbound_e
);
3624 ar
->dimen_type
[i
] = DIMEN_ELEMENT
;
3626 gfc_free_expr (ar
->start
[i
]);
3627 ar
->start
[i
] = get_operand (INTRINSIC_PLUS
, nindex
, lbound
);
3629 gfc_free_expr (ar
->end
[i
]);
3631 gfc_free_expr (ar
->stride
[i
]);
3632 ar
->stride
[i
] = NULL
;
3633 gfc_simplify_expr (ar
->start
[i
], 0);
3635 else if (was_fullref
)
3637 gfc_internal_error ("Scalarization using DIMEN_RANGE unimplemented");
3646 /* Helper function to check for a dimen vector as subscript. */
3649 has_dimen_vector_ref (gfc_expr
*e
)
3654 ar
= gfc_find_array_ref (e
);
3656 if (ar
->type
== AR_FULL
)
3659 for (i
=0; i
<ar
->dimen
; i
++)
3660 if (ar
->dimen_type
[i
] == DIMEN_VECTOR
)
3666 /* If handed an expression of the form
3670 check if A can be handled by matmul and return if there is an uneven number
3671 of CONJG calls. Return a pointer to the array when everything is OK, NULL
3672 otherwise. The caller has to check for the correct rank. */
3675 check_conjg_transpose_variable (gfc_expr
*e
, bool *conjg
, bool *transpose
)
3682 if (e
->expr_type
== EXPR_VARIABLE
)
3684 gcc_assert (e
->rank
== 1 || e
->rank
== 2);
3687 else if (e
->expr_type
== EXPR_FUNCTION
)
3689 if (e
->value
.function
.isym
== NULL
)
3692 if (e
->value
.function
.isym
->id
== GFC_ISYM_CONJG
)
3694 else if (e
->value
.function
.isym
->id
== GFC_ISYM_TRANSPOSE
)
3695 *transpose
= !*transpose
;
3701 e
= e
->value
.function
.actual
->expr
;
3708 /* Inline assignments of the form c = matmul(a,b).
3709 Handle only the cases currently where b and c are rank-two arrays.
3711 This basically translates the code to
3717 do k=0, size(a, 2)-1
3718 do i=0, size(a, 1)-1
3719 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) =
3720 c(i * stride(c,1) + lbound(c,1), j * stride(c,2) + lbound(c,2)) +
3721 a(i * stride(a,1) + lbound(a,1), k * stride(a,2) + lbound(a,2)) *
3722 b(k * stride(b,1) + lbound(b,1), j * stride(b,2) + lbound(b,2))
3731 inline_matmul_assign (gfc_code
**c
, int *walk_subtrees
,
3732 void *data ATTRIBUTE_UNUSED
)
3735 gfc_expr
*expr1
, *expr2
;
3736 gfc_expr
*matrix_a
, *matrix_b
;
3737 gfc_actual_arglist
*a
, *b
;
3738 gfc_code
*do_1
, *do_2
, *do_3
, *assign_zero
, *assign_matmul
;
3740 gfc_expr
*u1
, *u2
, *u3
;
3742 gfc_expr
*ascalar
, *bscalar
, *cscalar
;
3744 gfc_expr
*var_1
, *var_2
, *var_3
;
3747 gfc_intrinsic_op op_times
, op_plus
;
3748 enum matrix_case m_case
;
3750 gfc_code
*if_limit
= NULL
;
3751 gfc_code
**next_code_point
;
3752 bool conjg_a
, conjg_b
, transpose_a
, transpose_b
;
3754 if (co
->op
!= EXEC_ASSIGN
)
3757 if (in_where
|| in_assoc_list
)
3760 /* The BLOCKS generated for the temporary variables and FORALL don't
3762 if (forall_level
> 0)
3765 /* For now don't do anything in OpenMP workshare, it confuses
3766 its translation, which expects only the allowed statements in there.
3767 We should figure out how to parallelize this eventually. */
3768 if (in_omp_workshare
)
3773 if (expr2
->expr_type
!= EXPR_FUNCTION
3774 || expr2
->value
.function
.isym
== NULL
3775 || expr2
->value
.function
.isym
->id
!= GFC_ISYM_MATMUL
)
3779 inserted_block
= NULL
;
3780 changed_statement
= NULL
;
3782 a
= expr2
->value
.function
.actual
;
3783 matrix_a
= check_conjg_transpose_variable (a
->expr
, &conjg_a
, &transpose_a
);
3784 if (matrix_a
== NULL
)
3788 matrix_b
= check_conjg_transpose_variable (b
->expr
, &conjg_b
, &transpose_b
);
3789 if (matrix_b
== NULL
)
3792 if (has_dimen_vector_ref (expr1
) || has_dimen_vector_ref (matrix_a
)
3793 || has_dimen_vector_ref (matrix_b
))
3796 /* We do not handle data dependencies yet. */
3797 if (gfc_check_dependency (expr1
, matrix_a
, true)
3798 || gfc_check_dependency (expr1
, matrix_b
, true))
3802 if (matrix_a
->rank
== 2)
3806 if (matrix_b
->rank
== 2 && !transpose_b
)
3811 if (matrix_b
->rank
== 1)
3813 else /* matrix_b->rank == 2 */
3822 else /* matrix_a->rank == 1 */
3824 if (matrix_b
->rank
== 2)
3834 ns
= insert_block ();
3836 /* Assign the type of the zero expression for initializing the resulting
3837 array, and the expression (+ and * for real, integer and complex;
3838 .and. and .or for logical. */
3840 switch(expr1
->ts
.type
)
3843 zero_e
= gfc_get_int_expr (expr1
->ts
.kind
, &expr1
->where
, 0);
3844 op_times
= INTRINSIC_TIMES
;
3845 op_plus
= INTRINSIC_PLUS
;
3849 op_times
= INTRINSIC_AND
;
3850 op_plus
= INTRINSIC_OR
;
3851 zero_e
= gfc_get_logical_expr (expr1
->ts
.kind
, &expr1
->where
,
3855 zero_e
= gfc_get_constant_expr (BT_REAL
, expr1
->ts
.kind
,
3857 mpfr_set_si (zero_e
->value
.real
, 0, GFC_RND_MODE
);
3858 op_times
= INTRINSIC_TIMES
;
3859 op_plus
= INTRINSIC_PLUS
;
3863 zero_e
= gfc_get_constant_expr (BT_COMPLEX
, expr1
->ts
.kind
,
3865 mpc_set_si_si (zero_e
->value
.complex, 0, 0, GFC_RND_MODE
);
3866 op_times
= INTRINSIC_TIMES
;
3867 op_plus
= INTRINSIC_PLUS
;
3875 current_code
= &ns
->code
;
3877 /* Freeze the references, keeping track of how many temporary variables were
3880 freeze_references (matrix_a
);
3881 freeze_references (matrix_b
);
3882 freeze_references (expr1
);
3885 next_code_point
= current_code
;
3888 next_code_point
= &ns
->code
;
3889 for (i
=0; i
<n_vars
; i
++)
3890 next_code_point
= &(*next_code_point
)->next
;
3893 /* Take care of the inline flag. If the limit check evaluates to a
3894 constant, dead code elimination will eliminate the unneeded branch. */
3896 if (m_case
== A2B2
&& flag_inline_matmul_limit
> 0)
3898 if_limit
= inline_limit_check (matrix_a
, matrix_b
, m_case
);
3900 /* Insert the original statement into the else branch. */
3901 if_limit
->block
->block
->next
= co
;
3904 /* ... and the new ones go into the original one. */
3905 *next_code_point
= if_limit
;
3906 next_code_point
= &if_limit
->block
->next
;
3909 assign_zero
= XCNEW (gfc_code
);
3910 assign_zero
->op
= EXEC_ASSIGN
;
3911 assign_zero
->loc
= co
->loc
;
3912 assign_zero
->expr1
= gfc_copy_expr (expr1
);
3913 assign_zero
->expr2
= zero_e
;
3915 /* Handle the reallocation, if needed. */
3916 if (flag_realloc_lhs
&& gfc_is_reallocatable_lhs (expr1
))
3918 gfc_code
*lhs_alloc
;
3920 /* Only need to check a single dimension for the A2B2 case for
3921 bounds checking, the rest will be allocated. Also check this
3924 if ((gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
) && (m_case
== A2B2
|| m_case
== A2B1
))
3929 a2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 2);
3930 b1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 1);
3931 test
= runtime_error_ne (b1
, a2
, "Dimension of array B incorrect "
3932 "in MATMUL intrinsic: Is %ld, should be %ld");
3933 *next_code_point
= test
;
3934 next_code_point
= &test
->next
;
3938 lhs_alloc
= matmul_lhs_realloc (expr1
, matrix_a
, matrix_b
, m_case
);
3940 *next_code_point
= lhs_alloc
;
3941 next_code_point
= &lhs_alloc
->next
;
3944 else if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
3947 gfc_expr
*a2
, *b1
, *c1
, *c2
, *a1
, *b2
;
3949 if (m_case
== A2B2
|| m_case
== A2B1
)
3951 a2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 2);
3952 b1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 1);
3953 test
= runtime_error_ne (b1
, a2
, "Dimension of array B incorrect "
3954 "in MATMUL intrinsic: Is %ld, should be %ld");
3955 *next_code_point
= test
;
3956 next_code_point
= &test
->next
;
3958 c1
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 1);
3959 a1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 1);
3962 test
= runtime_error_ne (c1
, a1
, "Incorrect extent in return array in "
3963 "MATMUL intrinsic for dimension 1: "
3964 "is %ld, should be %ld");
3965 else if (m_case
== A2B1
)
3966 test
= runtime_error_ne (c1
, a1
, "Incorrect extent in return array in "
3967 "MATMUL intrinsic: "
3968 "is %ld, should be %ld");
3971 *next_code_point
= test
;
3972 next_code_point
= &test
->next
;
3974 else if (m_case
== A1B2
)
3976 a1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 1);
3977 b1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 1);
3978 test
= runtime_error_ne (b1
, a1
, "Dimension of array B incorrect "
3979 "in MATMUL intrinsic: Is %ld, should be %ld");
3980 *next_code_point
= test
;
3981 next_code_point
= &test
->next
;
3983 c1
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 1);
3984 b2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 2);
3986 test
= runtime_error_ne (c1
, b2
, "Incorrect extent in return array in "
3987 "MATMUL intrinsic: "
3988 "is %ld, should be %ld");
3990 *next_code_point
= test
;
3991 next_code_point
= &test
->next
;
3996 c2
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 2);
3997 b2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 2);
3998 test
= runtime_error_ne (c2
, b2
, "Incorrect extent in return array in "
3999 "MATMUL intrinsic for dimension 2: is %ld, should be %ld");
4001 *next_code_point
= test
;
4002 next_code_point
= &test
->next
;
4005 if (m_case
== A2B2T
)
4007 c1
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 1);
4008 a1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 1);
4009 test
= runtime_error_ne (c1
, a1
, "Incorrect extent in return array in "
4010 "MATMUL intrinsic for dimension 1: "
4011 "is %ld, should be %ld");
4013 *next_code_point
= test
;
4014 next_code_point
= &test
->next
;
4016 c2
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 2);
4017 b1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 1);
4018 test
= runtime_error_ne (c2
, b1
, "Incorrect extent in return array in "
4019 "MATMUL intrinsic for dimension 2: "
4020 "is %ld, should be %ld");
4021 *next_code_point
= test
;
4022 next_code_point
= &test
->next
;
4024 a2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 2);
4025 b2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 2);
4027 test
= runtime_error_ne (b2
, a2
, "Incorrect extent in argument B in "
4028 "MATMUL intrnisic for dimension 2: "
4029 "is %ld, should be %ld");
4030 *next_code_point
= test
;
4031 next_code_point
= &test
->next
;
4035 if (m_case
== A2TB2
)
4037 c1
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 1);
4038 a2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 2);
4040 test
= runtime_error_ne (c1
, a2
, "Incorrect extent in return array in "
4041 "MATMUL intrinsic for dimension 1: "
4042 "is %ld, should be %ld");
4044 *next_code_point
= test
;
4045 next_code_point
= &test
->next
;
4047 c2
= get_array_inq_function (GFC_ISYM_SIZE
, expr1
, 2);
4048 b2
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 2);
4049 test
= runtime_error_ne (c2
, b2
, "Incorrect extent in return array in "
4050 "MATMUL intrinsic for dimension 2: "
4051 "is %ld, should be %ld");
4052 *next_code_point
= test
;
4053 next_code_point
= &test
->next
;
4055 a1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_a
, 1);
4056 b1
= get_array_inq_function (GFC_ISYM_SIZE
, matrix_b
, 1);
4058 test
= runtime_error_ne (b1
, a1
, "Incorrect extent in argument B in "
4059 "MATMUL intrnisic for dimension 2: "
4060 "is %ld, should be %ld");
4061 *next_code_point
= test
;
4062 next_code_point
= &test
->next
;
4067 *next_code_point
= assign_zero
;
4069 zero
= gfc_get_int_expr (gfc_index_integer_kind
, &co
->loc
, 0);
4071 assign_matmul
= XCNEW (gfc_code
);
4072 assign_matmul
->op
= EXEC_ASSIGN
;
4073 assign_matmul
->loc
= co
->loc
;
4075 /* Get the bounds for the loops, create them and create the scalarized
4081 inline_limit_check (matrix_a
, matrix_b
, m_case
);
4083 u1
= get_size_m1 (matrix_b
, 2);
4084 u2
= get_size_m1 (matrix_a
, 2);
4085 u3
= get_size_m1 (matrix_a
, 1);
4087 do_1
= create_do_loop (gfc_copy_expr (zero
), u1
, NULL
, &co
->loc
, ns
);
4088 do_2
= create_do_loop (gfc_copy_expr (zero
), u2
, NULL
, &co
->loc
, ns
);
4089 do_3
= create_do_loop (gfc_copy_expr (zero
), u3
, NULL
, &co
->loc
, ns
);
4091 do_1
->block
->next
= do_2
;
4092 do_2
->block
->next
= do_3
;
4093 do_3
->block
->next
= assign_matmul
;
4095 var_1
= do_1
->ext
.iterator
->var
;
4096 var_2
= do_2
->ext
.iterator
->var
;
4097 var_3
= do_3
->ext
.iterator
->var
;
4101 cscalar
= scalarized_expr (co
->expr1
, list
, 2);
4105 ascalar
= scalarized_expr (matrix_a
, list
, 2);
4109 bscalar
= scalarized_expr (matrix_b
, list
, 2);
4114 inline_limit_check (matrix_a
, matrix_b
, m_case
);
4116 u1
= get_size_m1 (matrix_b
, 1);
4117 u2
= get_size_m1 (matrix_a
, 2);
4118 u3
= get_size_m1 (matrix_a
, 1);
4120 do_1
= create_do_loop (gfc_copy_expr (zero
), u1
, NULL
, &co
->loc
, ns
);
4121 do_2
= create_do_loop (gfc_copy_expr (zero
), u2
, NULL
, &co
->loc
, ns
);
4122 do_3
= create_do_loop (gfc_copy_expr (zero
), u3
, NULL
, &co
->loc
, ns
);
4124 do_1
->block
->next
= do_2
;
4125 do_2
->block
->next
= do_3
;
4126 do_3
->block
->next
= assign_matmul
;
4128 var_1
= do_1
->ext
.iterator
->var
;
4129 var_2
= do_2
->ext
.iterator
->var
;
4130 var_3
= do_3
->ext
.iterator
->var
;
4134 cscalar
= scalarized_expr (co
->expr1
, list
, 2);
4138 ascalar
= scalarized_expr (matrix_a
, list
, 2);
4142 bscalar
= scalarized_expr (matrix_b
, list
, 2);
4147 inline_limit_check (matrix_a
, matrix_b
, m_case
);
4149 u1
= get_size_m1 (matrix_a
, 2);
4150 u2
= get_size_m1 (matrix_b
, 2);
4151 u3
= get_size_m1 (matrix_a
, 1);
4153 do_1
= create_do_loop (gfc_copy_expr (zero
), u1
, NULL
, &co
->loc
, ns
);
4154 do_2
= create_do_loop (gfc_copy_expr (zero
), u2
, NULL
, &co
->loc
, ns
);
4155 do_3
= create_do_loop (gfc_copy_expr (zero
), u3
, NULL
, &co
->loc
, ns
);
4157 do_1
->block
->next
= do_2
;
4158 do_2
->block
->next
= do_3
;
4159 do_3
->block
->next
= assign_matmul
;
4161 var_1
= do_1
->ext
.iterator
->var
;
4162 var_2
= do_2
->ext
.iterator
->var
;
4163 var_3
= do_3
->ext
.iterator
->var
;
4167 cscalar
= scalarized_expr (co
->expr1
, list
, 2);
4171 ascalar
= scalarized_expr (matrix_a
, list
, 2);
4175 bscalar
= scalarized_expr (matrix_b
, list
, 2);
4180 u1
= get_size_m1 (matrix_b
, 1);
4181 u2
= get_size_m1 (matrix_a
, 1);
4183 do_1
= create_do_loop (gfc_copy_expr (zero
), u1
, NULL
, &co
->loc
, ns
);
4184 do_2
= create_do_loop (gfc_copy_expr (zero
), u2
, NULL
, &co
->loc
, ns
);
4186 do_1
->block
->next
= do_2
;
4187 do_2
->block
->next
= assign_matmul
;
4189 var_1
= do_1
->ext
.iterator
->var
;
4190 var_2
= do_2
->ext
.iterator
->var
;
4193 cscalar
= scalarized_expr (co
->expr1
, list
, 1);
4197 ascalar
= scalarized_expr (matrix_a
, list
, 2);
4200 bscalar
= scalarized_expr (matrix_b
, list
, 1);
4205 u1
= get_size_m1 (matrix_b
, 2);
4206 u2
= get_size_m1 (matrix_a
, 1);
4208 do_1
= create_do_loop (gfc_copy_expr (zero
), u1
, NULL
, &co
->loc
, ns
);
4209 do_2
= create_do_loop (gfc_copy_expr (zero
), u2
, NULL
, &co
->loc
, ns
);
4211 do_1
->block
->next
= do_2
;
4212 do_2
->block
->next
= assign_matmul
;
4214 var_1
= do_1
->ext
.iterator
->var
;
4215 var_2
= do_2
->ext
.iterator
->var
;
4218 cscalar
= scalarized_expr (co
->expr1
, list
, 1);
4221 ascalar
= scalarized_expr (matrix_a
, list
, 1);
4225 bscalar
= scalarized_expr (matrix_b
, list
, 2);
4233 /* Build the conjg call around the variables. Set the typespec manually
4234 because gfc_build_intrinsic_call sometimes gets this wrong. */
4239 ascalar
= gfc_build_intrinsic_call (ns
, GFC_ISYM_CONJG
, "conjg",
4240 matrix_a
->where
, 1, ascalar
);
4248 bscalar
= gfc_build_intrinsic_call (ns
, GFC_ISYM_CONJG
, "conjg",
4249 matrix_b
->where
, 1, bscalar
);
4252 /* First loop comes after the zero assignment. */
4253 assign_zero
->next
= do_1
;
4255 /* Build the assignment expression in the loop. */
4256 assign_matmul
->expr1
= gfc_copy_expr (cscalar
);
4258 mult
= get_operand (op_times
, ascalar
, bscalar
);
4259 assign_matmul
->expr2
= get_operand (op_plus
, cscalar
, mult
);
4261 /* If we don't want to keep the original statement around in
4262 the else branch, we can free it. */
4264 if (if_limit
== NULL
)
4265 gfc_free_statements(co
);
4269 gfc_free_expr (zero
);
4275 /* Code for index interchange for loops which are grouped together in DO
4276 CONCURRENT or FORALL statements. This is currently only applied if the
4277 iterations are grouped together in a single statement.
4279 For this transformation, it is assumed that memory access in strides is
4280 expensive, and that loops which access later indices (which access memory
4281 in bigger strides) should be moved to the first loops.
4283 For this, a loop over all the statements is executed, counting the times
4284 that the loop iteration values are accessed in each index. The loop
4285 indices are then sorted to minimize access to later indices from inner
4288 /* Type for holding index information. */
4292 gfc_forall_iterator
*fa
;
4294 int n
[GFC_MAX_DIMENSIONS
];
4297 /* Callback function to determine if an expression is the
4298 corresponding variable. */
4301 has_var (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
, void *data
)
4303 gfc_expr
*expr
= *e
;
4306 if (expr
->expr_type
!= EXPR_VARIABLE
)
4309 sym
= (gfc_symbol
*) data
;
4310 return sym
== expr
->symtree
->n
.sym
;
4313 /* Callback function to calculate the cost of a certain index. */
4316 index_cost (gfc_expr
**e
, int *walk_subtrees ATTRIBUTE_UNUSED
,
4326 if (expr
->expr_type
!= EXPR_VARIABLE
)
4330 for (ref
= expr
->ref
; ref
; ref
= ref
->next
)
4332 if (ref
->type
== REF_ARRAY
)
4338 if (ar
== NULL
|| ar
->type
!= AR_ELEMENT
)
4341 ind
= (ind_type
*) data
;
4342 for (i
= 0; i
< ar
->dimen
; i
++)
4344 for (j
=0; ind
[j
].sym
!= NULL
; j
++)
4346 if (gfc_expr_walker (&ar
->start
[i
], has_var
, (void *) (ind
[j
].sym
)))
4353 /* Callback function for qsort, to sort the loop indices. */
4356 loop_comp (const void *e1
, const void *e2
)
4358 const ind_type
*i1
= (const ind_type
*) e1
;
4359 const ind_type
*i2
= (const ind_type
*) e2
;
4362 for (i
=GFC_MAX_DIMENSIONS
-1; i
>= 0; i
--)
4364 if (i1
->n
[i
] != i2
->n
[i
])
4365 return i1
->n
[i
] - i2
->n
[i
];
4367 /* All other things being equal, let's not change the ordering. */
4368 return i2
->num
- i1
->num
;
4371 /* Main function to do the index interchange. */
4374 index_interchange (gfc_code
**c
, int *walk_subtrees ATTRIBUTE_UNUSED
,
4375 void *data ATTRIBUTE_UNUSED
)
4380 gfc_forall_iterator
*fa
;
4384 if (co
->op
!= EXEC_FORALL
&& co
->op
!= EXEC_DO_CONCURRENT
)
4388 for (fa
= co
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
4391 /* Nothing to reorder. */
4395 ind
= XALLOCAVEC (ind_type
, n_iter
+ 1);
4398 for (fa
= co
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
4400 ind
[i
].sym
= fa
->var
->symtree
->n
.sym
;
4402 for (j
=0; j
<GFC_MAX_DIMENSIONS
; j
++)
4407 ind
[n_iter
].sym
= NULL
;
4408 ind
[n_iter
].fa
= NULL
;
4410 gfc_code_walker (c
, gfc_dummy_code_callback
, index_cost
, (void *) ind
);
4411 qsort ((void *) ind
, n_iter
, sizeof (ind_type
), loop_comp
);
4413 /* Do the actual index interchange. */
4414 co
->ext
.forall_iterator
= fa
= ind
[0].fa
;
4415 for (i
=1; i
<n_iter
; i
++)
4417 fa
->next
= ind
[i
].fa
;
4422 if (flag_warn_frontend_loop_interchange
)
4424 for (i
=1; i
<n_iter
; i
++)
4426 if (ind
[i
-1].num
> ind
[i
].num
)
4428 gfc_warning (OPT_Wfrontend_loop_interchange
,
4429 "Interchanging loops at %L", &co
->loc
);
4438 #define WALK_SUBEXPR(NODE) \
4441 result = gfc_expr_walker (&(NODE), exprfn, data); \
4446 #define WALK_SUBEXPR_TAIL(NODE) e = &(NODE); continue
4448 /* Walk expression *E, calling EXPRFN on each expression in it. */
4451 gfc_expr_walker (gfc_expr
**e
, walk_expr_fn_t exprfn
, void *data
)
4455 int walk_subtrees
= 1;
4456 gfc_actual_arglist
*a
;
4460 int result
= exprfn (e
, &walk_subtrees
, data
);
4464 switch ((*e
)->expr_type
)
4467 WALK_SUBEXPR ((*e
)->value
.op
.op1
);
4468 WALK_SUBEXPR_TAIL ((*e
)->value
.op
.op2
);
4471 for (a
= (*e
)->value
.function
.actual
; a
; a
= a
->next
)
4472 WALK_SUBEXPR (a
->expr
);
4476 WALK_SUBEXPR ((*e
)->value
.compcall
.base_object
);
4477 for (a
= (*e
)->value
.compcall
.actual
; a
; a
= a
->next
)
4478 WALK_SUBEXPR (a
->expr
);
4481 case EXPR_STRUCTURE
:
4483 for (c
= gfc_constructor_first ((*e
)->value
.constructor
); c
;
4484 c
= gfc_constructor_next (c
))
4486 if (c
->iterator
== NULL
)
4487 WALK_SUBEXPR (c
->expr
);
4491 WALK_SUBEXPR (c
->expr
);
4493 WALK_SUBEXPR (c
->iterator
->var
);
4494 WALK_SUBEXPR (c
->iterator
->start
);
4495 WALK_SUBEXPR (c
->iterator
->end
);
4496 WALK_SUBEXPR (c
->iterator
->step
);
4500 if ((*e
)->expr_type
!= EXPR_ARRAY
)
4503 /* Fall through to the variable case in order to walk the
4507 case EXPR_SUBSTRING
:
4509 for (r
= (*e
)->ref
; r
; r
= r
->next
)
4518 if (ar
->type
== AR_SECTION
|| ar
->type
== AR_ELEMENT
)
4520 for (i
=0; i
< ar
->dimen
; i
++)
4522 WALK_SUBEXPR (ar
->start
[i
]);
4523 WALK_SUBEXPR (ar
->end
[i
]);
4524 WALK_SUBEXPR (ar
->stride
[i
]);
4531 WALK_SUBEXPR (r
->u
.ss
.start
);
4532 WALK_SUBEXPR (r
->u
.ss
.end
);
4548 #define WALK_SUBCODE(NODE) \
4551 result = gfc_code_walker (&(NODE), codefn, exprfn, data); \
4557 /* Walk code *C, calling CODEFN on each gfc_code node in it and calling EXPRFN
4558 on each expression in it. If any of the hooks returns non-zero, that
4559 value is immediately returned. If the hook sets *WALK_SUBTREES to 0,
4560 no subcodes or subexpressions are traversed. */
4563 gfc_code_walker (gfc_code
**c
, walk_code_fn_t codefn
, walk_expr_fn_t exprfn
,
4566 for (; *c
; c
= &(*c
)->next
)
4568 int walk_subtrees
= 1;
4569 int result
= codefn (c
, &walk_subtrees
, data
);
4576 gfc_actual_arglist
*a
;
4578 gfc_association_list
*alist
;
4579 bool saved_in_omp_workshare
;
4580 bool saved_in_where
;
4582 /* There might be statement insertions before the current code,
4583 which must not affect the expression walker. */
4586 saved_in_omp_workshare
= in_omp_workshare
;
4587 saved_in_where
= in_where
;
4593 WALK_SUBCODE (co
->ext
.block
.ns
->code
);
4594 if (co
->ext
.block
.assoc
)
4596 bool saved_in_assoc_list
= in_assoc_list
;
4598 in_assoc_list
= true;
4599 for (alist
= co
->ext
.block
.assoc
; alist
; alist
= alist
->next
)
4600 WALK_SUBEXPR (alist
->target
);
4602 in_assoc_list
= saved_in_assoc_list
;
4609 WALK_SUBEXPR (co
->ext
.iterator
->var
);
4610 WALK_SUBEXPR (co
->ext
.iterator
->start
);
4611 WALK_SUBEXPR (co
->ext
.iterator
->end
);
4612 WALK_SUBEXPR (co
->ext
.iterator
->step
);
4624 case EXEC_ASSIGN_CALL
:
4625 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
4626 WALK_SUBEXPR (a
->expr
);
4630 WALK_SUBEXPR (co
->expr1
);
4631 for (a
= co
->ext
.actual
; a
; a
= a
->next
)
4632 WALK_SUBEXPR (a
->expr
);
4636 WALK_SUBEXPR (co
->expr1
);
4638 for (b
= co
->block
; b
; b
= b
->block
)
4641 for (cp
= b
->ext
.block
.case_list
; cp
; cp
= cp
->next
)
4643 WALK_SUBEXPR (cp
->low
);
4644 WALK_SUBEXPR (cp
->high
);
4646 WALK_SUBCODE (b
->next
);
4651 case EXEC_DEALLOCATE
:
4654 for (a
= co
->ext
.alloc
.list
; a
; a
= a
->next
)
4655 WALK_SUBEXPR (a
->expr
);
4660 case EXEC_DO_CONCURRENT
:
4662 gfc_forall_iterator
*fa
;
4663 for (fa
= co
->ext
.forall_iterator
; fa
; fa
= fa
->next
)
4665 WALK_SUBEXPR (fa
->var
);
4666 WALK_SUBEXPR (fa
->start
);
4667 WALK_SUBEXPR (fa
->end
);
4668 WALK_SUBEXPR (fa
->stride
);
4670 if (co
->op
== EXEC_FORALL
)
4676 WALK_SUBEXPR (co
->ext
.open
->unit
);
4677 WALK_SUBEXPR (co
->ext
.open
->file
);
4678 WALK_SUBEXPR (co
->ext
.open
->status
);
4679 WALK_SUBEXPR (co
->ext
.open
->access
);
4680 WALK_SUBEXPR (co
->ext
.open
->form
);
4681 WALK_SUBEXPR (co
->ext
.open
->recl
);
4682 WALK_SUBEXPR (co
->ext
.open
->blank
);
4683 WALK_SUBEXPR (co
->ext
.open
->position
);
4684 WALK_SUBEXPR (co
->ext
.open
->action
);
4685 WALK_SUBEXPR (co
->ext
.open
->delim
);
4686 WALK_SUBEXPR (co
->ext
.open
->pad
);
4687 WALK_SUBEXPR (co
->ext
.open
->iostat
);
4688 WALK_SUBEXPR (co
->ext
.open
->iomsg
);
4689 WALK_SUBEXPR (co
->ext
.open
->convert
);
4690 WALK_SUBEXPR (co
->ext
.open
->decimal
);
4691 WALK_SUBEXPR (co
->ext
.open
->encoding
);
4692 WALK_SUBEXPR (co
->ext
.open
->round
);
4693 WALK_SUBEXPR (co
->ext
.open
->sign
);
4694 WALK_SUBEXPR (co
->ext
.open
->asynchronous
);
4695 WALK_SUBEXPR (co
->ext
.open
->id
);
4696 WALK_SUBEXPR (co
->ext
.open
->newunit
);
4697 WALK_SUBEXPR (co
->ext
.open
->share
);
4698 WALK_SUBEXPR (co
->ext
.open
->cc
);
4702 WALK_SUBEXPR (co
->ext
.close
->unit
);
4703 WALK_SUBEXPR (co
->ext
.close
->status
);
4704 WALK_SUBEXPR (co
->ext
.close
->iostat
);
4705 WALK_SUBEXPR (co
->ext
.close
->iomsg
);
4708 case EXEC_BACKSPACE
:
4712 WALK_SUBEXPR (co
->ext
.filepos
->unit
);
4713 WALK_SUBEXPR (co
->ext
.filepos
->iostat
);
4714 WALK_SUBEXPR (co
->ext
.filepos
->iomsg
);
4718 WALK_SUBEXPR (co
->ext
.inquire
->unit
);
4719 WALK_SUBEXPR (co
->ext
.inquire
->file
);
4720 WALK_SUBEXPR (co
->ext
.inquire
->iomsg
);
4721 WALK_SUBEXPR (co
->ext
.inquire
->iostat
);
4722 WALK_SUBEXPR (co
->ext
.inquire
->exist
);
4723 WALK_SUBEXPR (co
->ext
.inquire
->opened
);
4724 WALK_SUBEXPR (co
->ext
.inquire
->number
);
4725 WALK_SUBEXPR (co
->ext
.inquire
->named
);
4726 WALK_SUBEXPR (co
->ext
.inquire
->name
);
4727 WALK_SUBEXPR (co
->ext
.inquire
->access
);
4728 WALK_SUBEXPR (co
->ext
.inquire
->sequential
);
4729 WALK_SUBEXPR (co
->ext
.inquire
->direct
);
4730 WALK_SUBEXPR (co
->ext
.inquire
->form
);
4731 WALK_SUBEXPR (co
->ext
.inquire
->formatted
);
4732 WALK_SUBEXPR (co
->ext
.inquire
->unformatted
);
4733 WALK_SUBEXPR (co
->ext
.inquire
->recl
);
4734 WALK_SUBEXPR (co
->ext
.inquire
->nextrec
);
4735 WALK_SUBEXPR (co
->ext
.inquire
->blank
);
4736 WALK_SUBEXPR (co
->ext
.inquire
->position
);
4737 WALK_SUBEXPR (co
->ext
.inquire
->action
);
4738 WALK_SUBEXPR (co
->ext
.inquire
->read
);
4739 WALK_SUBEXPR (co
->ext
.inquire
->write
);
4740 WALK_SUBEXPR (co
->ext
.inquire
->readwrite
);
4741 WALK_SUBEXPR (co
->ext
.inquire
->delim
);
4742 WALK_SUBEXPR (co
->ext
.inquire
->encoding
);
4743 WALK_SUBEXPR (co
->ext
.inquire
->pad
);
4744 WALK_SUBEXPR (co
->ext
.inquire
->iolength
);
4745 WALK_SUBEXPR (co
->ext
.inquire
->convert
);
4746 WALK_SUBEXPR (co
->ext
.inquire
->strm_pos
);
4747 WALK_SUBEXPR (co
->ext
.inquire
->asynchronous
);
4748 WALK_SUBEXPR (co
->ext
.inquire
->decimal
);
4749 WALK_SUBEXPR (co
->ext
.inquire
->pending
);
4750 WALK_SUBEXPR (co
->ext
.inquire
->id
);
4751 WALK_SUBEXPR (co
->ext
.inquire
->sign
);
4752 WALK_SUBEXPR (co
->ext
.inquire
->size
);
4753 WALK_SUBEXPR (co
->ext
.inquire
->round
);
4757 WALK_SUBEXPR (co
->ext
.wait
->unit
);
4758 WALK_SUBEXPR (co
->ext
.wait
->iostat
);
4759 WALK_SUBEXPR (co
->ext
.wait
->iomsg
);
4760 WALK_SUBEXPR (co
->ext
.wait
->id
);
4765 WALK_SUBEXPR (co
->ext
.dt
->io_unit
);
4766 WALK_SUBEXPR (co
->ext
.dt
->format_expr
);
4767 WALK_SUBEXPR (co
->ext
.dt
->rec
);
4768 WALK_SUBEXPR (co
->ext
.dt
->advance
);
4769 WALK_SUBEXPR (co
->ext
.dt
->iostat
);
4770 WALK_SUBEXPR (co
->ext
.dt
->size
);
4771 WALK_SUBEXPR (co
->ext
.dt
->iomsg
);
4772 WALK_SUBEXPR (co
->ext
.dt
->id
);
4773 WALK_SUBEXPR (co
->ext
.dt
->pos
);
4774 WALK_SUBEXPR (co
->ext
.dt
->asynchronous
);
4775 WALK_SUBEXPR (co
->ext
.dt
->blank
);
4776 WALK_SUBEXPR (co
->ext
.dt
->decimal
);
4777 WALK_SUBEXPR (co
->ext
.dt
->delim
);
4778 WALK_SUBEXPR (co
->ext
.dt
->pad
);
4779 WALK_SUBEXPR (co
->ext
.dt
->round
);
4780 WALK_SUBEXPR (co
->ext
.dt
->sign
);
4781 WALK_SUBEXPR (co
->ext
.dt
->extra_comma
);
4784 case EXEC_OMP_PARALLEL
:
4785 case EXEC_OMP_PARALLEL_DO
:
4786 case EXEC_OMP_PARALLEL_DO_SIMD
:
4787 case EXEC_OMP_PARALLEL_SECTIONS
:
4789 in_omp_workshare
= false;
4791 /* This goto serves as a shortcut to avoid code
4792 duplication or a larger if or switch statement. */
4793 goto check_omp_clauses
;
4795 case EXEC_OMP_WORKSHARE
:
4796 case EXEC_OMP_PARALLEL_WORKSHARE
:
4798 in_omp_workshare
= true;
4802 case EXEC_OMP_CRITICAL
:
4803 case EXEC_OMP_DISTRIBUTE
:
4804 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO
:
4805 case EXEC_OMP_DISTRIBUTE_PARALLEL_DO_SIMD
:
4806 case EXEC_OMP_DISTRIBUTE_SIMD
:
4808 case EXEC_OMP_DO_SIMD
:
4809 case EXEC_OMP_ORDERED
:
4810 case EXEC_OMP_SECTIONS
:
4811 case EXEC_OMP_SINGLE
:
4812 case EXEC_OMP_END_SINGLE
:
4814 case EXEC_OMP_TASKLOOP
:
4815 case EXEC_OMP_TASKLOOP_SIMD
:
4816 case EXEC_OMP_TARGET
:
4817 case EXEC_OMP_TARGET_DATA
:
4818 case EXEC_OMP_TARGET_ENTER_DATA
:
4819 case EXEC_OMP_TARGET_EXIT_DATA
:
4820 case EXEC_OMP_TARGET_PARALLEL
:
4821 case EXEC_OMP_TARGET_PARALLEL_DO
:
4822 case EXEC_OMP_TARGET_PARALLEL_DO_SIMD
:
4823 case EXEC_OMP_TARGET_SIMD
:
4824 case EXEC_OMP_TARGET_TEAMS
:
4825 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE
:
4826 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4827 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4828 case EXEC_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD
:
4829 case EXEC_OMP_TARGET_UPDATE
:
4831 case EXEC_OMP_TEAMS
:
4832 case EXEC_OMP_TEAMS_DISTRIBUTE
:
4833 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO
:
4834 case EXEC_OMP_TEAMS_DISTRIBUTE_PARALLEL_DO_SIMD
:
4835 case EXEC_OMP_TEAMS_DISTRIBUTE_SIMD
:
4837 /* Come to this label only from the
4838 EXEC_OMP_PARALLEL_* cases above. */
4842 if (co
->ext
.omp_clauses
)
4844 gfc_omp_namelist
*n
;
4845 static int list_types
[]
4846 = { OMP_LIST_ALIGNED
, OMP_LIST_LINEAR
, OMP_LIST_DEPEND
,
4847 OMP_LIST_MAP
, OMP_LIST_TO
, OMP_LIST_FROM
};
4849 WALK_SUBEXPR (co
->ext
.omp_clauses
->if_expr
);
4850 WALK_SUBEXPR (co
->ext
.omp_clauses
->final_expr
);
4851 WALK_SUBEXPR (co
->ext
.omp_clauses
->num_threads
);
4852 WALK_SUBEXPR (co
->ext
.omp_clauses
->chunk_size
);
4853 WALK_SUBEXPR (co
->ext
.omp_clauses
->safelen_expr
);
4854 WALK_SUBEXPR (co
->ext
.omp_clauses
->simdlen_expr
);
4855 WALK_SUBEXPR (co
->ext
.omp_clauses
->num_teams
);
4856 WALK_SUBEXPR (co
->ext
.omp_clauses
->device
);
4857 WALK_SUBEXPR (co
->ext
.omp_clauses
->thread_limit
);
4858 WALK_SUBEXPR (co
->ext
.omp_clauses
->dist_chunk_size
);
4859 WALK_SUBEXPR (co
->ext
.omp_clauses
->grainsize
);
4860 WALK_SUBEXPR (co
->ext
.omp_clauses
->hint
);
4861 WALK_SUBEXPR (co
->ext
.omp_clauses
->num_tasks
);
4862 WALK_SUBEXPR (co
->ext
.omp_clauses
->priority
);
4863 for (idx
= 0; idx
< OMP_IF_LAST
; idx
++)
4864 WALK_SUBEXPR (co
->ext
.omp_clauses
->if_exprs
[idx
]);
4866 idx
< sizeof (list_types
) / sizeof (list_types
[0]);
4868 for (n
= co
->ext
.omp_clauses
->lists
[list_types
[idx
]];
4870 WALK_SUBEXPR (n
->expr
);
4877 WALK_SUBEXPR (co
->expr1
);
4878 WALK_SUBEXPR (co
->expr2
);
4879 WALK_SUBEXPR (co
->expr3
);
4880 WALK_SUBEXPR (co
->expr4
);
4881 for (b
= co
->block
; b
; b
= b
->block
)
4883 WALK_SUBEXPR (b
->expr1
);
4884 WALK_SUBEXPR (b
->expr2
);
4885 WALK_SUBCODE (b
->next
);
4888 if (co
->op
== EXEC_FORALL
)
4891 if (co
->op
== EXEC_DO
)
4894 if (co
->op
== EXEC_IF
)
4897 if (co
->op
== EXEC_SELECT
)
4900 in_omp_workshare
= saved_in_omp_workshare
;
4901 in_where
= saved_in_where
;