OSDN Git Service

2011-12-29 Thomas Koenig <tkoenig@gcc.gnu.org>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 Dec 2011 09:20:01 +0000 (09:20 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 29 Dec 2011 09:20:01 +0000 (09:20 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182720 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/dependency.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/function_optimize_9.f90 [new file with mode: 0644]

index cf74c46..d79478d 100644 (file)
@@ -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
index 96c4e5f..a2cf21d 100644 (file)
@@ -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;
index 732c7d1..3063567 100644 (file)
@@ -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 (file)
index 0000000..350ce9a
--- /dev/null
@@ -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" } }