2 Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
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 2, 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 COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 /* dependency.c -- Expression dependency analysis code. */
23 /* There's probably quite a bit of duplication in this file. We currently
24 have different dependency checking functions for different types
25 if dependencies. Ideally these would probably be merged. */
30 #include "dependency.h"
32 /* static declarations */
34 enum range {LHS, RHS, MID};
36 /* Dependency types. These must be in reverse order of priority. */
40 GFC_DEP_EQUAL, /* Identical Ranges. */
41 GFC_DEP_FORWARD, /* eg. a(1:3), a(2:4). */
42 GFC_DEP_OVERLAP, /* May overlap in some other way. */
43 GFC_DEP_NODEP /* Distinct ranges. */
48 #define IS_ARRAY_EXPLICIT(as) ((as->type == AS_EXPLICIT ? 1 : 0))
51 /* Returns 1 if the expr is an integer constant value 1, 0 if it is not or
52 def if the value could not be determined. */
55 gfc_expr_is_one (gfc_expr * expr, int def)
57 gcc_assert (expr != NULL);
59 if (expr->expr_type != EXPR_CONSTANT)
62 if (expr->ts.type != BT_INTEGER)
65 return mpz_cmp_si (expr->value.integer, 1) == 0;
69 /* Compare two values. Returns 0 if e1 == e2, -1 if e1 < e2, +1 if e1 > e2,
70 and -2 if the relationship could not be determined. */
73 gfc_dep_compare_expr (gfc_expr * e1, gfc_expr * e2)
77 if (e1->expr_type != e2->expr_type)
80 switch (e1->expr_type)
83 if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
86 i = mpz_cmp (e1->value.integer, e2->value.integer);
94 if (e1->ref || e2->ref)
96 if (e1->symtree->n.sym == e2->symtree->n.sym)
106 /* Returns 1 if the two ranges are the same, 0 if they are not, and def
107 if the results are indeterminate. N is the dimension to compare. */
110 gfc_is_same_range (gfc_array_ref * ar1, gfc_array_ref * ar2, int n, int def)
116 /* TODO: More sophisticated range comparison. */
117 gcc_assert (ar1 && ar2);
119 gcc_assert (ar1->dimen_type[n] == ar2->dimen_type[n]);
123 /* Check for mismatching strides. A NULL stride means a stride of 1. */
126 i = gfc_expr_is_one (e1, -1);
134 i = gfc_expr_is_one (e2, -1);
142 i = gfc_dep_compare_expr (e1, e2);
148 /* The strides match. */
150 /* Check the range start. */
155 /* Use the bound of the array if no bound is specified. */
157 e1 = ar1->as->lower[n];
160 e2 = ar2->as->lower[n];
162 /* Check we have values for both. */
166 i = gfc_dep_compare_expr (e1, e2);
173 /* Check the range end. */
178 /* Use the bound of the array if no bound is specified. */
180 e1 = ar1->as->upper[n];
183 e2 = ar2->as->upper[n];
185 /* Check we have values for both. */
189 i = gfc_dep_compare_expr (e1, e2);
200 /* Some array-returning intrinsics can be implemented by reusing the
201 data from one of the array arguments. For example, TRANSPOSE does
202 not necessarily need to allocate new data: it can be implemented
203 by copying the original array's descriptor and simply swapping the
204 two dimension specifications.
206 If EXPR is a call to such an intrinsic, return the argument
207 whose data can be reused, otherwise return NULL. */
210 gfc_get_noncopying_intrinsic_argument (gfc_expr * expr)
212 if (expr->expr_type != EXPR_FUNCTION || !expr->value.function.isym)
215 switch (expr->value.function.isym->generic_id)
217 case GFC_ISYM_TRANSPOSE:
218 return expr->value.function.actual->expr;
226 /* Return true if the result of reference REF can only be constructed
227 using a temporary array. */
230 gfc_ref_needs_temporary_p (gfc_ref *ref)
236 for (; ref; ref = ref->next)
240 /* Vector dimensions are generally not monotonic and must be
241 handled using a temporary. */
242 if (ref->u.ar.type == AR_SECTION)
243 for (n = 0; n < ref->u.ar.dimen; n++)
244 if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
251 /* Within an array reference, character substrings generally
252 need a temporary. Character array strides are expressed as
253 multiples of the element size (consistent with other array
254 types), not in characters. */
265 /* Return true if array variable VAR could be passed to the same function
266 as argument EXPR without interfering with EXPR. INTENT is the intent
269 This is considerably less conservative than other dependencies
270 because many function arguments will already be copied into a
274 gfc_check_argument_var_dependency (gfc_expr * var, sym_intent intent,
277 gcc_assert (var->expr_type == EXPR_VARIABLE);
278 gcc_assert (var->rank > 0);
280 switch (expr->expr_type)
283 return (gfc_ref_needs_temporary_p (expr->ref)
284 || gfc_check_dependency (var, expr, 1));
287 return gfc_check_dependency (var, expr, 1);
290 if (intent != INTENT_IN && expr->inline_noncopying_intrinsic)
292 expr = gfc_get_noncopying_intrinsic_argument (expr);
293 return gfc_check_argument_var_dependency (var, intent, expr);
303 /* Like gfc_check_argument_var_dependency, but extended to any
304 array expression OTHER, not just variables. */
307 gfc_check_argument_dependency (gfc_expr * other, sym_intent intent,
310 switch (other->expr_type)
313 return gfc_check_argument_var_dependency (other, intent, expr);
316 if (other->inline_noncopying_intrinsic)
318 other = gfc_get_noncopying_intrinsic_argument (other);
319 return gfc_check_argument_dependency (other, INTENT_IN, expr);
329 /* Like gfc_check_argument_dependency, but check all the arguments in ACTUAL.
330 FNSYM is the function being called, or NULL if not known. */
333 gfc_check_fncall_dependency (gfc_expr * other, sym_intent intent,
334 gfc_symbol * fnsym, gfc_actual_arglist * actual)
336 gfc_formal_arglist *formal;
339 formal = fnsym ? fnsym->formal : NULL;
340 for (; actual; actual = actual->next, formal = formal ? formal->next : NULL)
344 /* Skip args which are not present. */
348 /* Skip intent(in) arguments if OTHER itself is intent(in). */
350 && intent == INTENT_IN
351 && formal->sym->attr.intent == INTENT_IN)
354 if (gfc_check_argument_dependency (other, intent, expr))
362 /* Return true if the statement body redefines the condition. Returns
363 true if expr2 depends on expr1. expr1 should be a single term
364 suitable for the lhs of an assignment. The IDENTICAL flag indicates
365 whether array references to the same symbol with identical range
366 references count as a dependency or not. Used for forall and where
367 statements. Also used with functions returning arrays without a
371 gfc_check_dependency (gfc_expr * expr1, gfc_expr * expr2, bool identical)
375 gfc_actual_arglist *actual;
377 gcc_assert (expr1->expr_type == EXPR_VARIABLE);
379 /* TODO: -fassume-no-pointer-aliasing */
380 if (expr1->symtree->n.sym->attr.pointer)
382 for (ref = expr1->ref; ref; ref = ref->next)
384 if (ref->type == REF_COMPONENT && ref->u.c.component->pointer)
388 switch (expr2->expr_type)
391 n = gfc_check_dependency (expr1, expr2->value.op.op1, identical);
394 if (expr2->value.op.op2)
395 return gfc_check_dependency (expr1, expr2->value.op.op2, identical);
399 if (expr2->symtree->n.sym->attr.pointer)
402 for (ref = expr2->ref; ref; ref = ref->next)
404 if (ref->type == REF_COMPONENT && ref->u.c.component->pointer)
408 if (expr1->symtree->n.sym != expr2->symtree->n.sym)
414 /* Identical ranges return 0, overlapping ranges return 1. */
416 /* Return zero if we refer to the same full arrays. */
417 if (expr1->ref->type == REF_ARRAY
418 && expr2->ref->type == REF_ARRAY
419 && expr1->ref->u.ar.type == AR_FULL
420 && expr2->ref->u.ar.type == AR_FULL
422 && !expr2->ref->next)
428 if (expr2->inline_noncopying_intrinsic)
430 /* Remember possible differences between elemental and
431 transformational functions. All functions inside a FORALL
433 for (actual = expr2->value.function.actual;
434 actual; actual = actual->next)
438 n = gfc_check_dependency (expr1, actual->expr, identical);
448 /* Probably ok in the majority of (constant) cases. */
457 /* Calculates size of the array reference using lower bound, upper bound
461 get_no_of_elements(mpz_t ele, gfc_expr * u1, gfc_expr * l1, gfc_expr * s1)
463 /* nNoOfEle = (u1-l1)/s1 */
465 mpz_sub (ele, u1->value.integer, l1->value.integer);
468 mpz_tdiv_q (ele, ele, s1->value.integer);
472 /* Returns if the ranges ((0..Y), (X1..X2)) overlap. */
474 static gfc_dependency
475 get_deps (mpz_t x1, mpz_t x2, mpz_t y)
480 start = mpz_cmp_ui (x1, 0);
481 end = mpz_cmp (x2, y);
483 /* Both ranges the same. */
484 if (start == 0 && end == 0)
485 return GFC_DEP_EQUAL;
487 /* Distinct ranges. */
488 if ((start < 0 && mpz_cmp_ui (x2, 0) < 0)
489 || (mpz_cmp (x1, y) > 0 && end > 0))
490 return GFC_DEP_NODEP;
492 /* Overlapping, but with corresponding elements of the second range
493 greater than the first. */
494 if (start > 0 && end > 0)
495 return GFC_DEP_FORWARD;
497 /* Overlapping in some other way. */
498 return GFC_DEP_OVERLAP;
502 /* Perform the same linear transformation on sections l and r such that
503 (l_start:l_end:l_stride) -> (0:no_of_elements)
504 (r_start:r_end:r_stride) -> (X1:X2)
505 Where r_end is implicit as both sections must have the same number of
507 Returns 0 on success, 1 of the transformation failed. */
508 /* TODO: Should this be (0:no_of_elements-1) */
511 transform_sections (mpz_t X1, mpz_t X2, mpz_t no_of_elements,
512 gfc_expr * l_start, gfc_expr * l_end, gfc_expr * l_stride,
513 gfc_expr * r_start, gfc_expr * r_stride)
515 if (NULL == l_start || NULL == l_end || NULL == r_start)
518 /* TODO : Currently we check the dependency only when start, end and stride
519 are constant. We could also check for equal (variable) values, and
520 common subexpressions, eg. x vs. x+1. */
522 if (l_end->expr_type != EXPR_CONSTANT
523 || l_start->expr_type != EXPR_CONSTANT
524 || r_start->expr_type != EXPR_CONSTANT
525 || ((NULL != l_stride) && (l_stride->expr_type != EXPR_CONSTANT))
526 || ((NULL != r_stride) && (r_stride->expr_type != EXPR_CONSTANT)))
532 get_no_of_elements (no_of_elements, l_end, l_start, l_stride);
534 mpz_sub (X1, r_start->value.integer, l_start->value.integer);
535 if (l_stride != NULL)
536 mpz_cdiv_q (X1, X1, l_stride->value.integer);
538 if (r_stride == NULL)
539 mpz_set (X2, no_of_elements);
541 mpz_mul (X2, no_of_elements, r_stride->value.integer);
543 if (l_stride != NULL)
544 mpz_cdiv_q (X2, X2, l_stride->value.integer);
545 mpz_add (X2, X2, X1);
551 /* Determines overlapping for two array sections. */
553 static gfc_dependency
554 gfc_check_section_vs_section (gfc_ref * lref, gfc_ref * rref, int n)
566 mpz_t no_of_elements;
573 /* If they are the same range, return without more ado. */
574 if (gfc_is_same_range (&l_ar, &r_ar, n, 0))
575 return GFC_DEP_EQUAL;
577 l_start = l_ar.start[n];
579 l_stride = l_ar.stride[n];
580 r_start = r_ar.start[n];
581 r_stride = r_ar.stride[n];
583 /* if l_start is NULL take it from array specifier */
584 if (NULL == l_start && IS_ARRAY_EXPLICIT(l_ar.as))
585 l_start = l_ar.as->lower[n];
587 /* if l_end is NULL take it from array specifier */
588 if (NULL == l_end && IS_ARRAY_EXPLICIT(l_ar.as))
589 l_end = l_ar.as->upper[n];
591 /* if r_start is NULL take it from array specifier */
592 if (NULL == r_start && IS_ARRAY_EXPLICIT(r_ar.as))
593 r_start = r_ar.as->lower[n];
597 mpz_init (no_of_elements);
599 if (transform_sections (X1, X2, no_of_elements,
600 l_start, l_end, l_stride,
602 dep = GFC_DEP_OVERLAP;
604 dep = get_deps (X1, X2, no_of_elements);
606 mpz_clear (no_of_elements);
613 /* Checks if the expr chk is inside the range left-right.
614 Returns GFC_DEP_NODEP if chk is outside the range,
615 GFC_DEP_OVERLAP otherwise.
616 Assumes left<=right. */
618 static gfc_dependency
619 gfc_is_inside_range (gfc_expr * chk, gfc_expr * left, gfc_expr * right)
625 s = gfc_dep_compare_expr (left, right);
627 return GFC_DEP_OVERLAP;
629 l = gfc_dep_compare_expr (chk, left);
630 r = gfc_dep_compare_expr (chk, right);
632 /* Check for indeterminate relationships. */
633 if (l == -2 || r == -2 || s == -2)
634 return GFC_DEP_OVERLAP;
638 /* When left>right we want to check for right <= chk <= left. */
639 if (l <= 0 || r >= 0)
640 return GFC_DEP_OVERLAP;
644 /* Otherwise check for left <= chk <= right. */
645 if (l >= 0 || r <= 0)
646 return GFC_DEP_OVERLAP;
649 return GFC_DEP_NODEP;
653 /* Determines overlapping for a single element and a section. */
655 static gfc_dependency
656 gfc_check_element_vs_section( gfc_ref * lref, gfc_ref * rref, int n)
666 l_start = l_ar.start[n] ;
667 r_start = r_ar.start[n] ;
668 r_end = r_ar.end[n] ;
669 if (NULL == r_start && IS_ARRAY_EXPLICIT (r_ar.as))
670 r_start = r_ar.as->lower[n];
671 if (NULL == r_end && IS_ARRAY_EXPLICIT (r_ar.as))
672 r_end = r_ar.as->upper[n];
673 if (NULL == r_start || NULL == r_end || l_start == NULL)
674 return GFC_DEP_OVERLAP;
676 return gfc_is_inside_range (l_start, r_end, r_start);
680 /* Determines overlapping for two single element array references. */
682 static gfc_dependency
683 gfc_check_element_vs_element (gfc_ref * lref, gfc_ref * rref, int n)
689 gfc_dependency nIsDep;
691 if (lref->type == REF_ARRAY && rref->type == REF_ARRAY)
695 l_start = l_ar.start[n] ;
696 r_start = r_ar.start[n] ;
697 if (gfc_dep_compare_expr (r_start, l_start) == 0)
698 nIsDep = GFC_DEP_EQUAL;
700 nIsDep = GFC_DEP_NODEP;
703 nIsDep = GFC_DEP_NODEP;
709 /* Finds if two array references are overlapping or not.
711 1 : array references are overlapping.
712 0 : array references are not overlapping. */
715 gfc_dep_resolver (gfc_ref * lref, gfc_ref * rref)
718 gfc_dependency fin_dep;
719 gfc_dependency this_dep;
722 fin_dep = GFC_DEP_ERROR;
723 /* Dependencies due to pointers should already have been identified.
724 We only need to check for overlapping array references. */
728 /* We're resolving from the same base symbol, so both refs should be
729 the same type. We traverse the reference chain intil we find ranges
730 that are not equal. */
731 gcc_assert (lref->type == rref->type);
735 /* The two ranges can't overlap if they are from different
737 if (lref->u.c.component != rref->u.c.component)
742 /* Substring overlaps are handled by the string assignment code. */
747 for (n=0; n < lref->u.ar.dimen; n++)
749 /* Assume dependency when either of array reference is vector
751 if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR
752 || rref->u.ar.dimen_type[n] == DIMEN_VECTOR)
754 if (lref->u.ar.dimen_type[n] == DIMEN_RANGE
755 && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
756 this_dep = gfc_check_section_vs_section (lref, rref, n);
757 else if (lref->u.ar.dimen_type[n] == DIMEN_ELEMENT
758 && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
759 this_dep = gfc_check_element_vs_section (lref, rref, n);
760 else if (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
761 && lref->u.ar.dimen_type[n] == DIMEN_RANGE)
762 this_dep = gfc_check_element_vs_section (rref, lref, n);
765 gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
766 && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT);
767 this_dep = gfc_check_element_vs_element (rref, lref, n);
770 /* If any dimension doesn't overlap, we have no dependency. */
771 if (this_dep == GFC_DEP_NODEP)
774 /* Overlap codes are in order of priority. We only need to
775 know the worst one.*/
776 if (this_dep > fin_dep)
779 /* Exactly matching and forward overlapping ranges don't cause a
781 if (fin_dep < GFC_DEP_OVERLAP)
784 /* Keep checking. We only have a dependency if
785 subsequent references also overlap. */
795 /* If we haven't seen any array refs then something went wrong. */
796 gcc_assert (fin_dep != GFC_DEP_ERROR);
798 if (fin_dep < GFC_DEP_OVERLAP)