From 124a8ce610d0f8d315d491810e4b69b686c9c6a8 Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Fri, 3 Sep 2010 16:16:34 +0000 Subject: [PATCH] re PR fortran/45159 (Unnecessary temporaries) 2010-09-03 Thomas Koenig PR fortran/45159 * dependency.c (gfc_deb_compare_expr): Compare equal for equal arglists for pure user functions, or for those intrinsic functions which are also pure. * intrinsics.c (add_conv): Mark conversion functions as pure. (add_char_conversions): Likewise. 2010-09-03 Thomas Koenig PR fortran/45159 * gfortran.dg/dependency_34.f90: New test. From-SVN: r163834 --- gcc/fortran/ChangeLog | 9 ++++ gcc/fortran/dependency.c | 55 +++++++++------------ gcc/fortran/intrinsic.c | 2 + gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gfortran.dg/dependency_34.f90 | 22 +++++++++ 5 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/dependency_34.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ad46b0aaede6..a5de32af4ab2 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2010-09-03 Thomas Koenig + + PR fortran/45159 + * dependency.c (gfc_deb_compare_expr): Compare equal for equal + arglists for pure user functions, or for those intrinsic + functions which are also pure. + * intrinsics.c (add_conv): Mark conversion functions as pure. + (add_char_conversions): Likewise. + 2010-09-03 Daniel Kraft PR fortran/34162 diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c index ab75bdee54ad..960155e04e3a 100644 --- a/gcc/fortran/dependency.c +++ b/gcc/fortran/dependency.c @@ -353,39 +353,32 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2) return -2; case EXPR_FUNCTION: - /* We can only compare calls to the same intrinsic function. */ - if (e1->value.function.isym == 0 || e2->value.function.isym == 0 - || e1->value.function.isym != e2->value.function.isym) + + /* PURE functions can be compared for argument equality. */ + if ((e1->value.function.esym && e2->value.function.esym + && e1->value.function.esym == e2->value.function.esym + && e1->value.function.esym->result->attr.pure) + || (e1->value.function.isym && e2->value.function.isym + && e1->value.function.isym == e2->value.function.isym + && e1->value.function.isym->pure)) + { + args1 = e1->value.function.actual; + args2 = e2->value.function.actual; + + /* Compare the argument lists for equality. */ + while (args1 && args2) + { + if (gfc_dep_compare_expr (args1->expr, args2->expr) != 0) + return -2; + args1 = args1->next; + args2 = args2->next; + } + return (args1 || args2) ? -2 : 0; + } + else return -2; + break; - args1 = e1->value.function.actual; - args2 = e2->value.function.actual; - - /* We should list the "constant" intrinsic functions. Those - without side-effects that provide equal results given equal - argument lists. */ - switch (e1->value.function.isym->id) - { - - case GFC_ISYM_REAL: - case GFC_ISYM_LOGICAL: - case GFC_ISYM_DBLE: - break; - - default: - return -2; - } - - /* Compare the argument lists for equality. */ - while (args1 && args2) - { - if (gfc_dep_compare_expr (args1->expr, args2->expr) != 0) - return -2; - args1 = args1->next; - args2 = args2->next; - } - return (args1 || args2) ? -2 : 0; - default: return -2; } diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index 0b469ae08fbf..817603564a46 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -3060,6 +3060,7 @@ add_conv (bt from_type, int from_kind, bt to_type, int to_kind, int standard) sym->simplify.cc = gfc_convert_constant; sym->standard = standard; sym->elemental = 1; + sym->pure = 1; sym->conversion = 1; sym->ts = to; sym->id = GFC_ISYM_CONVERSION; @@ -3210,6 +3211,7 @@ add_char_conversions (void) char_conversions[n].simplify.cc = gfc_convert_char_constant; char_conversions[n].standard = GFC_STD_F2003; char_conversions[n].elemental = 1; + char_conversions[n].pure = 1; char_conversions[n].conversion = 0; char_conversions[n].ts = to; char_conversions[n].id = GFC_ISYM_CONVERSION; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f9050a17de67..9fae7d703224 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-03 Thomas Koenig + + PR fortran/45159 + * gfortran.dg/dependency_34.f90: New test. + 2010-09-03 Steve Ellcey * gcc.dg/torture/pr44806.c: Add -std=c99 to access uint32_t. diff --git a/gcc/testsuite/gfortran.dg/dependency_34.f90 b/gcc/testsuite/gfortran.dg/dependency_34.f90 new file mode 100644 index 000000000000..82d286ebbcdf --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dependency_34.f90 @@ -0,0 +1,22 @@ +! { dg-do compile } +! { dg-options "-Warray-temporaries" } +module foo + implicit none +contains + integer pure function bar(i,j) + integer, intent(in) :: i,j + bar = 3 - i + 1 * abs(i) + j + end function bar +end module foo + +program main + use foo + implicit none + real a(10) + integer :: i + read (*,*) a, i + a(i:abs(i)) = a(i:abs(i)) + a(bar(i,i+2):2) = a(bar(i,i+2):2) + a(int(i,kind=2):5) = a(int(i,kind=2)+1:6) +end program main +! { dg-final { cleanup-modules "foo" } }