int gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse) { int n; gfc_dependency fin_dep; gfc_dependency this_dep; this_dep = GFC_DEP_ERROR; fin_dep = GFC_DEP_ERROR; /* Dependencies due to pointers should already have been identified. We only need to check for overlapping array references. */ while (lref && rref) { /* We're resolving from the same base symbol, so both refs should be the same type. We traverse the reference chain until we find ranges that are not equal. */ gcc_assert (lref->type == rref->type); switch (lref->type) { case REF_COMPONENT: /* The two ranges can't overlap if they are from different components. */ if (lref->u.c.component != rref->u.c.component) return 0; break; case REF_SUBSTRING: /* Substring overlaps are handled by the string assignment code if there is not an underlying dependency. */ return (fin_dep == GFC_DEP_OVERLAP) ? 1 : 0; case REF_ARRAY: if (ref_same_as_full_array (lref, rref)) return 0; if (ref_same_as_full_array (rref, lref)) return 0; if (lref->u.ar.dimen != rref->u.ar.dimen) { if (lref->u.ar.type == AR_FULL) fin_dep = gfc_full_array_ref_p (rref, NULL) ? GFC_DEP_EQUAL : GFC_DEP_OVERLAP; else if (rref->u.ar.type == AR_FULL) fin_dep = gfc_full_array_ref_p (lref, NULL) ? GFC_DEP_EQUAL : GFC_DEP_OVERLAP; else return 1; break; } for (n=0; n < lref->u.ar.dimen; n++) { /* Assume dependency when either of array reference is vector subscript. */ if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR || rref->u.ar.dimen_type[n] == DIMEN_VECTOR) return 1; if (lref->u.ar.dimen_type[n] == DIMEN_RANGE && rref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = gfc_check_section_vs_section (lref, rref, n); else if (lref->u.ar.dimen_type[n] == DIMEN_ELEMENT && rref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = gfc_check_element_vs_section (lref, rref, n); else if (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT && lref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = gfc_check_element_vs_section (rref, lref, n); else { gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT); this_dep = gfc_check_element_vs_element (rref, lref, n); } /* If any dimension doesn't overlap, we have no dependency. */ if (this_dep == GFC_DEP_NODEP) return 0; /* Now deal with the loop reversal logic: This only works on ranges and is activated by setting reverse[n] == GFC_CAN_REVERSE The ability to reverse or not is set by previous conditions in this dimension. If reversal is not activated, the value GFC_DEP_BACKWARD is reset to GFC_DEP_OVERLAP. */ if (rref->u.ar.dimen_type[n] == DIMEN_RANGE && lref->u.ar.dimen_type[n] == DIMEN_RANGE) { /* Set reverse if backward dependence and not inhibited. */ if (reverse && reverse[n] != GFC_CANNOT_REVERSE) reverse[n] = (this_dep == GFC_DEP_BACKWARD) ? GFC_REVERSE_SET : reverse[n]; /* Inhibit loop reversal if dependence not compatible. */ if (reverse && reverse[n] != GFC_REVERSE_NOT_SET && this_dep != GFC_DEP_EQUAL && this_dep != GFC_DEP_BACKWARD && this_dep != GFC_DEP_NODEP) { reverse[n] = GFC_CANNOT_REVERSE; if (this_dep != GFC_DEP_FORWARD) this_dep = GFC_DEP_OVERLAP; } /* If no intention of reversing or reversing is explicitly inhibited, convert backward dependence to overlap. */ if ((reverse == NULL && this_dep == GFC_DEP_BACKWARD) || (reverse && reverse[n] == GFC_CANNOT_REVERSE)) this_dep = GFC_DEP_OVERLAP; } /* Overlap codes are in order of priority. We only need to know the worst one.*/ if (this_dep > fin_dep) fin_dep = this_dep; } /* If this is an equal element, we have to keep going until we find the "real" array reference. */ if (lref->u.ar.type == AR_ELEMENT && rref->u.ar.type == AR_ELEMENT && fin_dep == GFC_DEP_EQUAL) break; /* Exactly matching and forward overlapping ranges don't cause a dependency. */ if (fin_dep < GFC_DEP_BACKWARD) return 0; /* Keep checking. We only have a dependency if subsequent references also overlap. */ break; default: gcc_unreachable (); } lref = lref->next; rref = rref->next; } /* If we haven't seen any array refs then something went wrong. */ gcc_assert (fin_dep != GFC_DEP_ERROR); /* Assume the worst if we nest to different depths. */ if (lref || rref) return 1; return fin_dep == GFC_DEP_OVERLAP; }
int gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref) { int n; gfc_dependency fin_dep; gfc_dependency this_dep; fin_dep = GFC_DEP_ERROR; /* Dependencies due to pointers should already have been identified. We only need to check for overlapping array references. */ while (lref && rref) { /* We're resolving from the same base symbol, so both refs should be the same type. We traverse the reference chain until we find ranges that are not equal. */ gcc_assert (lref->type == rref->type); switch (lref->type) { case REF_COMPONENT: /* The two ranges can't overlap if they are from different components. */ if (lref->u.c.component != rref->u.c.component) return 0; break; case REF_SUBSTRING: /* Substring overlaps are handled by the string assignment code if there is not an underlying dependency. */ return (fin_dep == GFC_DEP_OVERLAP) ? 1 : 0; case REF_ARRAY: if (ref_same_as_full_array (lref, rref)) return 0; if (ref_same_as_full_array (rref, lref)) return 0; if (lref->u.ar.dimen != rref->u.ar.dimen) { if (lref->u.ar.type == AR_FULL) fin_dep = gfc_full_array_ref_p (rref, NULL) ? GFC_DEP_EQUAL : GFC_DEP_OVERLAP; else if (rref->u.ar.type == AR_FULL) fin_dep = gfc_full_array_ref_p (lref, NULL) ? GFC_DEP_EQUAL : GFC_DEP_OVERLAP; else return 1; break; } for (n=0; n < lref->u.ar.dimen; n++) { /* Assume dependency when either of array reference is vector subscript. */ if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR || rref->u.ar.dimen_type[n] == DIMEN_VECTOR) return 1; if (lref->u.ar.dimen_type[n] == DIMEN_RANGE && rref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = gfc_check_section_vs_section (lref, rref, n); else if (lref->u.ar.dimen_type[n] == DIMEN_ELEMENT && rref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = gfc_check_element_vs_section (lref, rref, n); else if (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT && lref->u.ar.dimen_type[n] == DIMEN_RANGE) this_dep = gfc_check_element_vs_section (rref, lref, n); else { gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT); this_dep = gfc_check_element_vs_element (rref, lref, n); } /* If any dimension doesn't overlap, we have no dependency. */ if (this_dep == GFC_DEP_NODEP) return 0; /* Overlap codes are in order of priority. We only need to know the worst one.*/ if (this_dep > fin_dep) fin_dep = this_dep; } /* If this is an equal element, we have to keep going until we find the "real" array reference. */ if (lref->u.ar.type == AR_ELEMENT && rref->u.ar.type == AR_ELEMENT && fin_dep == GFC_DEP_EQUAL) break; /* Exactly matching and forward overlapping ranges don't cause a dependency. */ if (fin_dep < GFC_DEP_OVERLAP) return 0; /* Keep checking. We only have a dependency if subsequent references also overlap. */ break; default: gcc_unreachable (); } lref = lref->next; rref = rref->next; } /* If we haven't seen any array refs then something went wrong. */ gcc_assert (fin_dep != GFC_DEP_ERROR); /* Assume the worst if we nest to different depths. */ if (lref || rref) return 1; return fin_dep == GFC_DEP_OVERLAP; }