aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2016-07-19 21:25:33 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2016-07-19 21:25:33 +0000
commit6ed825558ec5df100d84c284c52618ec397456a5 (patch)
tree118193899a3b655d59e43f384407b7a266f4249c
parent4833f5615ea56f73106ca8537d0a8b50463fd164 (diff)
downloadgcc-6ed825558ec5df100d84c284c52618ec397456a5.zip
gcc-6ed825558ec5df100d84c284c52618ec397456a5.tar.gz
gcc-6ed825558ec5df100d84c284c52618ec397456a5.tar.bz2
re PR fortran/71902 (Unneeded temporary on reallocatable character assignment)
2016-07-19 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/71902 * dependency.c (gfc_check_dependency): Use dep_ref. Handle case if identical is true and two array element references differ. (gfc_dep_resovler): Move most of the code to dep_ref. (dep_ref): New function. * frontend-passes.c (realloc_string_callback): Name temporary variable "realloc_string". 2016-07-19 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/71902 * gfortran.dg/dependency_47.f90: New test. From-SVN: r238497
-rw-r--r--gcc/fortran/ChangeLog10
-rw-r--r--gcc/fortran/dependency.c79
-rw-r--r--gcc/fortran/frontend-passes.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/dependency_47.f9015
5 files changed, 96 insertions, 15 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 04335d9..2912fcb 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,13 @@
+2016-07-19 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/71902
+ * dependency.c (gfc_check_dependency): Use dep_ref. Handle case
+ if identical is true and two array element references differ.
+ (gfc_dep_resovler): Move most of the code to dep_ref.
+ (dep_ref): New function.
+ * frontend-passes.c (realloc_string_callback): Name temporary
+ variable "realloc_string".
+
2016-07-17 Fritz Reese <fritzoreese@gmail.com>
PR fortran/71523
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index f117de0..a873dbe 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -54,6 +54,8 @@ enum gfc_dependency
static gfc_dependency check_section_vs_section (gfc_array_ref *,
gfc_array_ref *, int);
+static gfc_dependency dep_ref (gfc_ref *, gfc_ref *, gfc_reverse *);
+
/* Returns 1 if the expr is an integer constant value 1, 0 if it is not or
def if the value could not be determined. */
@@ -1316,13 +1318,33 @@ gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
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);
+ {
+ gfc_dependency dep;
+ dep = dep_ref (expr1->ref, expr2->ref, NULL);
+ switch (dep)
+ {
+ case GFC_DEP_EQUAL:
+ return identical;
+
+ case GFC_DEP_FORWARD:
+ return 0;
+
+ case GFC_DEP_BACKWARD:
+ return 1;
+
+ case GFC_DEP_OVERLAP:
+ return 1;
+
+ case GFC_DEP_NODEP:
+ return 0;
+
+ default:
+ gcc_unreachable();
+ }
+ }
return 1;
@@ -2052,11 +2074,39 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
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. */
+ 0 : array references are identical or can be handled in a forward loop. */
int
gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
{
+ enum gfc_dependency dep;
+ dep = dep_ref (lref, rref, reverse);
+ switch (dep)
+ {
+ case GFC_DEP_EQUAL:
+ return 0;
+
+ case GFC_DEP_FORWARD:
+ return 0;
+
+ case GFC_DEP_BACKWARD:
+ return 2;
+
+ case GFC_DEP_OVERLAP:
+ return 1;
+
+ case GFC_DEP_NODEP:
+ return 0;
+
+ default:
+ gcc_unreachable();
+ }
+}
+
+
+static gfc_dependency
+dep_ref (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
+{
int n;
int m;
gfc_dependency fin_dep;
@@ -2079,21 +2129,22 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
/* The two ranges can't overlap if they are from different
components. */
if (lref->u.c.component != rref->u.c.component)
- return 0;
+ return GFC_DEP_NODEP;
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;
+
+ return fin_dep == GFC_DEP_ERROR ? GFC_DEP_NODEP : fin_dep;
case REF_ARRAY:
if (ref_same_as_full_array (lref, rref))
- return 0;
+ return GFC_DEP_EQUAL;
if (ref_same_as_full_array (rref, lref))
- return 0;
+ return GFC_DEP_EQUAL;
if (lref->u.ar.dimen != rref->u.ar.dimen)
{
@@ -2104,7 +2155,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
fin_dep = gfc_full_array_ref_p (lref, NULL) ? GFC_DEP_EQUAL
: GFC_DEP_OVERLAP;
else
- return 1;
+ return GFC_DEP_OVERLAP;
break;
}
@@ -2148,7 +2199,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
/* If any dimension doesn't overlap, we have no dependency. */
if (this_dep == GFC_DEP_NODEP)
- return 0;
+ return GFC_DEP_NODEP;
/* Now deal with the loop reversal logic: This only works on
ranges and is activated by setting
@@ -2215,7 +2266,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
/* Exactly matching and forward overlapping ranges don't cause a
dependency. */
if (fin_dep < GFC_DEP_BACKWARD)
- return 0;
+ return fin_dep == GFC_DEP_ERROR ? GFC_DEP_NODEP : fin_dep;
/* Keep checking. We only have a dependency if
subsequent references also overlap. */
@@ -2233,7 +2284,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
/* Assume the worst if we nest to different depths. */
if (lref || rref)
- return 1;
+ return GFC_DEP_OVERLAP;
- return fin_dep == GFC_DEP_OVERLAP;
+ return fin_dep;
}
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 9ae3421..d4dee47 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -185,7 +185,7 @@ realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
current_code = c;
inserted_block = NULL;
changed_statement = NULL;
- n = create_var (expr2, "trim");
+ n = create_var (expr2, "realloc_string");
co->expr2 = n;
return 0;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ceae017..47ca526 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-07-19 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/71902
+ * gfortran.dg/dependency_47.f90: New test.
+
2016-07-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/71916
diff --git a/gcc/testsuite/gfortran.dg/dependency_47.f90 b/gcc/testsuite/gfortran.dg/dependency_47.f90
new file mode 100644
index 0000000..eebc910
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependency_47.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! Make sure there is only one instance of a temporary variable here.
+! { dg-options "-fdump-tree-original" }
+
+SUBROUTINE prtdata(ilen)
+ INTEGER :: ilen
+ character(len=ilen), allocatable :: cline(:)
+ allocate(cline(2))
+ cline(1) = 'a'
+ cline(1)(2:3) = cline(1)(1:2)
+ cline(2) = cline(1)
+ print *,c
+END SUBROUTINE prtdata
+! { dg-final { scan-tree-dump-not "__var_2" "original" } }
+! { dg-final { scan-tree-dump-times "__var_1" 3 "original" } }