aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2012-04-07 16:38:11 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2012-04-07 16:38:11 +0000
commit8144d290d8ce582bbd50601b74dcfa811bae5c1c (patch)
treeb08aa45c1b30ee9777563511b083ff3029bd0c04 /gcc
parentfae61228ca65572ed01a23819be585b742bcfa62 (diff)
downloadgcc-8144d290d8ce582bbd50601b74dcfa811bae5c1c.zip
gcc-8144d290d8ce582bbd50601b74dcfa811bae5c1c.tar.gz
gcc-8144d290d8ce582bbd50601b74dcfa811bae5c1c.tar.bz2
re PR fortran/52893 (Moving functions out of implied DO loops)
2012-04-07 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/52893 * 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 * gfortran.dg/function_optimize_11.f90: New test. From-SVN: r186213
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/frontend-passes.c20
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/function_optimize_11.f9017
4 files changed, 46 insertions, 2 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 050f25e..2b9b03c 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2012-04-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/52893
+ * frontend-passes.c: Keep track of wether we are in an implicit
+ DO loop; do not do function elimination if we are.
+
2012-04-06 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/52668
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index a86982f..b20dabb 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -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,13 @@ 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. FIXME: We should check
+ if the functions do indeed depend on the iterator variable. */
+
+ 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 +592,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 +1152,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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3d67560..7743667 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-04-07 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/52893
+ * gfortran.dg/function_optimize_11.f90: New test.
+
2012-04-06 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/52668
diff --git a/gcc/testsuite/gfortran.dg/function_optimize_11.f90 b/gcc/testsuite/gfortran.dg/function_optimize_11.f90
new file mode 100644
index 0000000..2e4831b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/function_optimize_11.f90
@@ -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