From: Thomas Koenig <tkoenig@netcologne.de>
To: "fortran@gcc.gnu.org" <fortran@gcc.gnu.org>,
gcc-patches <gcc-patches@gcc.gnu.org>
Subject: [patch, fortran] Improve dependency checking
Date: Thu, 25 Jul 2019 13:08:00 -0000 [thread overview]
Message-ID: <a4fe61bf-8a6e-1f29-889b-a0304015c74d@netcologne.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 991 bytes --]
Hello world,
the attached pach does some more work in gfc_check_dependency for
the case where an identity between arguments would also lead
to problems.
It does not lead to removal of the warning with -Warray-temporaries,
because that is still generated by the call to library function.
Instead, I checked for the names of the variables which used to
be introduced by the matmul inlining code.
Regression-tested. OK for trunk?
Regards
Thomas
2019-07-25 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/65819
* dependency.h (gfc_dep_resovler): Add optional argument identical.
* dependency.c (gfc_check_dependency): Do not alway return 1 if
the symbol is the same. Pass on identical to gfc_dep_resolver.
(gfc_check_element_vs_element): Whitespace fix.
(gfc_dep_resolver): Adjust comment for function. If identical is
true, return 1 if any overlap has been found.
2019-07-25 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/65819
* gfortran.dg/dependency_54.f90: New test.
[-- Attachment #2: p1.diff --]
[-- Type: text/x-patch, Size: 3792 bytes --]
Index: dependency.c
===================================================================
--- dependency.c (Revision 273733)
+++ dependency.c (Arbeitskopie)
@@ -1351,13 +1351,10 @@ gfc_check_dependency (gfc_expr *expr1, gfc_expr *e
return 0;
}
- if (identical)
- return 1;
-
/* Identical and disjoint ranges return 0,
overlapping ranges return 1. */
if (expr1->ref && expr2->ref)
- return gfc_dep_resolver (expr1->ref, expr2->ref, NULL);
+ return gfc_dep_resolver (expr1->ref, expr2->ref, NULL, identical);
return 1;
@@ -1884,6 +1881,7 @@ gfc_check_element_vs_element (gfc_ref *lref, gfc_r
if (i > -2)
return GFC_DEP_NODEP;
+
return GFC_DEP_EQUAL;
}
@@ -2084,13 +2082,15 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref
/* Finds if two array references are overlapping or not.
Return value
- 2 : array references are overlapping but reversal of one or
+ 2 : array references are overlapping but reversal of one or
more dimensions will clear the dependency.
- 1 : array references are overlapping.
- 0 : array references are identical or not overlapping. */
+ 1 : array references are overlapping, or identical is true and
+ there is some kind of overlap.
+ 0 : array references are identical or not overlapping. */
int
-gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
+gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
+ bool identical)
{
int n;
int m;
@@ -2124,11 +2124,15 @@ int
case REF_ARRAY:
+ /* For now, treat all coarrays as dangerous. */
+ if (lref->u.ar.codimen || rref->u.ar.codimen)
+ return 1;
+
if (ref_same_as_full_array (lref, rref))
- return 0;
+ return identical;
if (ref_same_as_full_array (rref, lref))
- return 0;
+ return identical;
if (lref->u.ar.dimen != rref->u.ar.dimen)
{
@@ -2180,6 +2184,8 @@ int
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 (identical && this_dep == GFC_DEP_EQUAL)
+ this_dep = GFC_DEP_OVERLAP;
}
/* If any dimension doesn't overlap, we have no dependency. */
@@ -2240,6 +2246,9 @@ int
know the worst one.*/
update_fin_dep:
+ if (identical && this_dep == GFC_DEP_EQUAL)
+ this_dep = GFC_DEP_OVERLAP;
+
if (this_dep > fin_dep)
fin_dep = this_dep;
}
@@ -2253,7 +2262,7 @@ int
/* Exactly matching and forward overlapping ranges don't cause a
dependency. */
- if (fin_dep < GFC_DEP_BACKWARD)
+ if (fin_dep < GFC_DEP_BACKWARD && !identical)
return 0;
/* Keep checking. We only have a dependency if
@@ -2267,11 +2276,14 @@ int
rref = rref->next;
}
+ /* Assume the worst if we nest to different depths. */
+ if (lref || rref)
+ return 1;
+
/* 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)
+ if (identical && fin_dep != GFC_DEP_NODEP)
return 1;
return fin_dep == GFC_DEP_OVERLAP;
Index: dependency.h
===================================================================
--- dependency.h (Revision 273733)
+++ dependency.h (Arbeitskopie)
@@ -37,7 +37,7 @@ int gfc_check_fncall_dependency (gfc_expr *, sym_i
int gfc_check_dependency (gfc_expr *, gfc_expr *, bool);
int gfc_expr_is_one (gfc_expr *, int);
-int gfc_dep_resolver(gfc_ref *, gfc_ref *, gfc_reverse *);
+int gfc_dep_resolver(gfc_ref *, gfc_ref *, gfc_reverse *, bool identical = false);
int gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
gfc_expr * gfc_discard_nops (gfc_expr *);
[-- Attachment #3: dependency_54.f90 --]
[-- Type: text/x-fortran, Size: 864 bytes --]
! { dg-do run }
! { dg-additional-options "-fdump-tree-original -ffrontend-optimize" }
! PR 65819 - this used to cause a temporary in matmul inlining.
! Check that these are absent by looking for the names of the
! temporary variables.
program main
implicit none
real, dimension(3,3,3) :: f
real, dimension(3,3) :: res
real, dimension(2,3,3) :: backup
integer :: three
integer :: i
data f(1,:,:) /9*-42./
data f(2:3,:,:) /2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61/
data res /652, 772, 984, 2010, 2406, 3082, 3402, 4086, 5242/
three = 3
backup = f(2:3,:,:)
f(1, 1:three, :) = matmul(f(2,1:3,2:3), f(3,2:3,:))
if (any (res /= f(1,:,:))) stop 1
if (any (f(2:3,:,:) /= backup)) stop 2
end program main
! { dg-final { scan-tree-dump-not "mma" "original" } }
! { dg-final { scan-tree-dump-not "mmb" "original" } }
next reply other threads:[~2019-07-25 12:57 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-25 13:08 Thomas Koenig [this message]
2019-07-25 14:31 ` Steve Kargl
2019-07-25 14:52 ` Thomas Koenig
2019-07-25 16:26 ` Steve Kargl
2019-07-25 16:40 ` Thomas Koenig
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a4fe61bf-8a6e-1f29-889b-a0304015c74d@netcologne.de \
--to=tkoenig@netcologne.de \
--cc=fortran@gcc.gnu.org \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).