2010-09-03 Thomas Koenig <tkoenig@gcc.gnu.org>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Sep 2010 21:21:14 +0000 (21:21 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Sep 2010 21:21:14 +0000 (21:21 +0000)
* dump_parse_tree (gfc_run_passes):  Call optimize_namespace
instead of optimize_code.
(optimize_namespace):  New function.

2010-09-03  Thomas Koenig  <tkoenig@gcc.gnu.org>

* gfortran.dg/trim_optimize_2.f90:  New test.

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

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

index 27ff0fe..14c5fe4 100644 (file)
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 /* Forward declarations.  */
 
 static void strip_function_call (gfc_expr *);
+static void optimize_namespace (gfc_namespace *);
 static void optimize_assignment (gfc_code *);
 static void optimize_expr_0 (gfc_expr *);
 static bool optimize_expr (gfc_expr *);
@@ -41,10 +42,21 @@ static void optimize_actual_arglist (gfc_actual_arglist *);
    optimization pass is run.  */
 
 void
-gfc_run_passes (gfc_namespace * ns)
+gfc_run_passes (gfc_namespace *ns)
 {
   if (optimize)
-    optimize_code (ns->code);
+    optimize_namespace (ns);
+}
+
+/* Optimize a namespace, including all contained namespaces.  */
+
+static void
+optimize_namespace (gfc_namespace *ns)
+{
+  optimize_code (ns->code);
+
+  for (ns = ns->contained; ns; ns = ns->sibling)
+    optimize_namespace (ns);
 }
 
 static void
diff --git a/gcc/testsuite/gfortran.dg/trim_optimize_2.f90 b/gcc/testsuite/gfortran.dg/trim_optimize_2.f90
new file mode 100644 (file)
index 0000000..b7ae1e3
--- /dev/null
@@ -0,0 +1,37 @@
+! { dg-do run }
+! { dg-options "-O -fdump-tree-original" }
+! Optimize unnecessary TRIMs in contained namespaces too.
+module faz
+  implicit none
+contains
+  subroutine bar
+    character(len=3) :: a
+    character(len=4) :: b,c
+    b = 'abcd'
+    a = trim(b)
+    c = trim(trim(a))
+    if (a /= 'abc') call abort
+    if (c /= 'abc') call abort
+  end subroutine bar
+end module faz
+
+program main
+  use faz
+  implicit none
+  call foo
+  call bar
+contains
+  subroutine foo
+    character(len=3) :: a
+    character(len=4) :: b,c
+    b = 'abcd'
+    a = trim(b)
+    c = trim(trim(a))
+    if (a /= 'abc') call abort
+    if (c /= 'abc') call abort
+  end subroutine foo
+end program main
+
+! { dg-final { scan-tree-dump-times "memmove" 4 "original" } }
+! { dg-final { scan-tree-dump-times "string_trim" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }