OSDN Git Service

2012-04-07 Thomas Koenig <tkoenig@gcc.gnu.org>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 7 Apr 2012 20:27:02 +0000 (20:27 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 7 Apr 2012 20:27:02 +0000 (20:27 +0000)
PR fortran/52893
Backport from trunk
* frontend-passes.c:  Keep track of wether we are in an implicit
DO loop; do not do function elimination if we are.

2012-04-07  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/52893
Backport from trunk
* gfortran.dg/function_optimize_11.f90:  New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@186215 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/frontend-passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/function_optimize_11.f90 [new file with mode: 0644]

index 897b012..9ed5a06 100644 (file)
@@ -1,5 +1,12 @@
 2012-04-07  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
+       PR fortran/52893
+       Backport from trunk
+       * frontend-passes.c:  Keep track of wether we are in an implicit
+       DO loop; do not do function elimination if we are.
+
+2012-04-07  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
        PR fortran/52668
        Backport from trunk
        * module.c:  Only mark symbols as use_only if they have been
index a86982f..d9986d2 100644 (file)
@@ -70,6 +70,10 @@ static int forall_level;
 
 static bool in_omp_workshare;
 
+/* Keep track of iterators for array constructors.  */
+
+static int iterator_level;
+
 /* Entry point - run all passes for a namespace.  So far, only an
    optimization pass is run.  */
 
@@ -179,6 +183,12 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
   if (forall_level > 0)
     return 0;
 
+  /* Function elimination inside an iterator could lead to functions
+     which depend on iterator variables being moved outside.  */
+
+  if (iterator_level > 0)
+    return 0;
+
   /* If we don't know the shape at compile time, we create an allocatable
      temporary variable to hold the intermediate result, but only if
      allocation on assignment is active.  */
@@ -581,6 +591,7 @@ optimize_namespace (gfc_namespace *ns)
 
   current_ns = ns;
   forall_level = 0;
+  iterator_level = 0;
   in_omp_workshare = false;
 
   gfc_code_walker (&ns->code, convert_do_while, dummy_expr_callback, NULL);
@@ -1140,9 +1151,13 @@ gfc_expr_walker (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
            for (c = gfc_constructor_first ((*e)->value.constructor); c;
                 c = gfc_constructor_next (c))
              {
-               WALK_SUBEXPR (c->expr);
-               if (c->iterator != NULL)
+               if (c->iterator == NULL)
+                 WALK_SUBEXPR (c->expr);
+               else
                  {
+                   iterator_level ++;
+                   WALK_SUBEXPR (c->expr);
+                   iterator_level --;
                    WALK_SUBEXPR (c->iterator->var);
                    WALK_SUBEXPR (c->iterator->start);
                    WALK_SUBEXPR (c->iterator->end);
index fcbbe12..6420f44 100644 (file)
@@ -1,5 +1,11 @@
 2012-04-07  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
+       PR fortran/52893
+       Backport from trunk
+       * gfortran.dg/function_optimize_11.f90:  New test.
+
+2012-04-07  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
        PR fortran/52668
        Backport from trunk
        * gfortran.dg/use_only_6.f90: New test.
diff --git a/gcc/testsuite/gfortran.dg/function_optimize_11.f90 b/gcc/testsuite/gfortran.dg/function_optimize_11.f90
new file mode 100644 (file)
index 0000000..2e4831b
--- /dev/null
@@ -0,0 +1,17 @@
+! { dg-do run }
+! { dg-options "-ffrontend-optimize" }
+! Do not move common functions out of implicit DO loop constructors.
+program test
+  integer, parameter :: N = 4
+  integer, parameter :: dp=kind(1.d0)
+  real(kind=dp), parameter :: pi=4*atan(1._dp)
+  real(kind=dp), parameter :: eps = 1.e-14_dp
+  real(kind=dp) :: h1(0:N-1), h2(0:N-1)
+  integer i
+
+  i = 1
+  h1 = [(cos(2*pi*mod(i*k,N)/N),k=0,N/2), &
+       & (sin(2*pi*mod(i*k,N)/N),k=1,N/2-1)]
+  h2 = (/ 1._dp, 0._dp, -1._dp, 1._dp /)
+  if (any(abs(h1 - h2) > eps)) call abort
+end program test