aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2011-12-29 09:20:01 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2011-12-29 09:20:01 +0000
commitd8e5eb5711e236c0304becf5bd0ee28dfc3f67d5 (patch)
treed10f25bdc5da73a713310bc59080aacef1f576df /gcc
parent663b7c930535f94f4a2dc3309dae30d22faab1b8 (diff)
downloadgcc-d8e5eb5711e236c0304becf5bd0ee28dfc3f67d5.zip
gcc-d8e5eb5711e236c0304becf5bd0ee28dfc3f67d5.tar.gz
gcc-d8e5eb5711e236c0304becf5bd0ee28dfc3f67d5.tar.bz2
dependency.c (gfc_dep_compare_functions): Document new behavior for REALs and complex.
2011-12-29 Thomas Koenig <tkoenig@gcc.gnu.org> * dependency.c (gfc_dep_compare_functions): Document new behavior for REALs and complex. Add comment to cases where only INTEGERs are handled. Compare REAL and COMPLEX constants, returning 0 and -2 only. Add assert to make sure that only integer constants are compared. 2011-12-29 Thomas Koenig <tkoenig@gcc.gnu.org> * gfortran.dg/function_optimize_9.f90: New test. From-SVN: r182720
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog8
-rw-r--r--gcc/fortran/dependency.c39
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gfortran.dg/function_optimize_9.f9023
4 files changed, 68 insertions, 6 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index cf74c46..d79478d 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,11 @@
+2011-12-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ * dependency.c (gfc_dep_compare_functions): Document
+ new behavior for REALs and complex. Add comment to cases
+ where only INTEGERs are handled. Compare REAL and COMPLEX
+ constants, returning 0 and -2 only. Add assert to make
+ sure that only integer constants are compared.
+
2011-12-19 Tobias Burnus <burnus@net-b.de>
PR fortran/51605
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 96c4e5f..a2cf21d 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -245,7 +245,9 @@ gfc_dep_compare_functions (gfc_expr *e1, gfc_expr *e2, bool impure_ok)
* 0 if e1 == e2
* -1 if e1 < e2
* -2 if the relationship could not be determined
- * -3 if e1 /= e2, but we cannot tell which one is larger. */
+ * -3 if e1 /= e2, but we cannot tell which one is larger.
+ REAL and COMPLEX constants are only compared for equality
+ or inequality; if they are unequal, -2 is returned in all cases. */
int
gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
@@ -303,7 +305,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_PLUS)
{
- /* Compare X+C vs. X. */
+ /* Compare X+C vs. X, for INTEGER only. */
if (e1->value.op.op2->expr_type == EXPR_CONSTANT
&& e1->value.op.op2->ts.type == BT_INTEGER
&& gfc_dep_compare_expr (e1->value.op.op1, e2) == 0)
@@ -342,7 +344,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
}
- /* Compare X vs. X+C. */
+ /* Compare X vs. X+C, for INTEGER only. */
if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
{
if (e2->value.op.op2->expr_type == EXPR_CONSTANT
@@ -351,7 +353,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
return -mpz_sgn (e2->value.op.op2->value.integer);
}
- /* Compare X-C vs. X. */
+ /* Compare X-C vs. X, for INTEGER only. */
if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_MINUS)
{
if (e1->value.op.op2->expr_type == EXPR_CONSTANT
@@ -415,7 +417,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
}
- /* Compare X vs. X-C. */
+ /* Compare X vs. X-C, for INTEGER only. */
if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
{
if (e2->value.op.op2->expr_type == EXPR_CONSTANT
@@ -434,9 +436,34 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
if (e1->ts.type == BT_CHARACTER && e2->ts.type == BT_CHARACTER)
return gfc_compare_string (e1, e2);
+ /* Compare REAL and COMPLEX constants. Because of the
+ traps and pitfalls associated with comparing
+ a + 1.0 with a + 0.5, check for equality only. */
+ if (e2->expr_type == EXPR_CONSTANT)
+ {
+ if (e1->ts.type == BT_REAL && e2->ts.type == BT_REAL)
+ {
+ if (mpfr_cmp (e1->value.real, e2->value.real) == 0)
+ return 0;
+ else
+ return -2;
+ }
+ else if (e1->ts.type == BT_COMPLEX && e2->ts.type == BT_COMPLEX)
+ {
+ if (mpc_cmp (e1->value.complex, e2->value.complex) == 0)
+ return 0;
+ else
+ return -2;
+ }
+ }
+
if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
return -2;
+ /* For INTEGER, all cases where e2 is not constant should have
+ been filtered out above. */
+ gcc_assert (e2->expr_type == EXPR_CONSTANT);
+
i = mpz_cmp (e1->value.integer, e2->value.integer);
if (i == 0)
return 0;
@@ -465,7 +492,7 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
else if (e1->value.op.op == INTRINSIC_TIMES
&& gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op2) == 0
&& gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op1) == 0)
- /* Commutativity of multiplication. */
+ /* Commutativity of multiplication; addition is handled above. */
return 0;
return -2;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 732c7d1..3063567 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2011-12-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ * gfortran.dg/function_optimize_9.f90: New test.
+
2011-12-27 Fabien ChĂȘne <fabien@gcc.gnu.org>
PR c++/23211
diff --git a/gcc/testsuite/gfortran.dg/function_optimize_9.f90 b/gcc/testsuite/gfortran.dg/function_optimize_9.f90
new file mode 100644
index 0000000..350ce9a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/function_optimize_9.f90
@@ -0,0 +1,23 @@
+! { dg-do compile }
+! { dg-options "-O -fdump-tree-original" }
+program main
+ integer, parameter :: n=100
+ real, parameter :: pi=4*atan(1.)
+ real, parameter :: tmax=20.
+ real, parameter :: dt = tmax/(2*pi)/real(n)
+ real, parameter :: t0 = dt/30.
+ integer :: i
+ interface
+ pure function purefunc(x)
+ real :: purefunc
+ real, intent(in) :: x
+ end function purefunc
+ end interface
+ real :: a(n)
+ do i=1,n
+ a(i) = purefunc(dt*i + t0) * 3. + 2 * purefunc(t0 + i*dt)
+ end do
+ print *,a
+end program main
+! { dg-final { scan-tree-dump-times "purefunc" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }