diff mbox

[fortran] Some more function elimination tweaks

Message ID 4DD432EA.4040307@netcologne.de
State New
Headers show

Commit Message

Thomas Koenig May 18, 2011, 8:58 p.m. UTC
Hello world,

the attached patch does the following:

- It removes the restriction on functions returning allocatables
   for elimination (unnecessary since the introduction of allocatable
   temporary variables)

- It allows character function elimination if the character length is
   a constant known at compile time

- It removes introducing temporary variables for the TRANSFER function;
   this is better be handled by the middle-end.

Regression-tested.

OK for trunk?

	Thomas

2011-05-18  Thomas Koenig  <tkoenig@gcc.gnu.org>

         * frontend-passes.c (cfe_register_funcs):  Also register
         character functions if their charlens are known and constant.
         Also register allocatable functions.

2011-05-18  Thomas Koenig  <tkoenig@gcc.gnu.org>

         * gfortran.dg/function_optimize_8.f90:  New test case.
! { dg-do compile }
! { dg-options "-O -fdump-tree-original" }
! Check that duplicate function calls are removed for
! - Functions returning allocatables
! - Character functions with known length
module x
  implicit none
contains
  pure function myfunc(x) result(y)
    integer, intent(in) :: x
    integer, dimension(:), allocatable :: y
    allocate (y(3))
    y(1) = x
    y(2) = 2*x
    y(3) = 3*x
  end function myfunc

  pure function mychar(x) result(r)
    integer, intent(in) :: x
    character(len=2) :: r
    r = achar(x + iachar('0')) // achar(x + iachar('1'))
  end function mychar
end module x

program main
  use x
  implicit none
  integer :: n
  character(len=20) :: line
  n = 3
  write (unit=line,fmt='(3I2)') myfunc(n) + myfunc(n)
  if (line /= ' 61218') call abort
  write (unit=line,fmt='(A)') mychar(2) // mychar(2)
  if (line /= '2323') call abort
end program main
! { dg-final { scan-tree-dump-times "myfunc" 2 "original" } }
! { dg-final { scan-tree-dump-times "mychar" 2 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
! { dg-final { cleanup-modules "x" } }

Comments

Steve Kargl May 21, 2011, 4:36 p.m. UTC | #1
On Wed, May 18, 2011 at 10:58:18PM +0200, Thomas Koenig wrote:
> 
> - It removes the restriction on functions returning allocatables
>   for elimination (unnecessary since the introduction of allocatable
>   temporary variables)
> 
> - It allows character function elimination if the character length is
>   a constant known at compile time
> 
> - It removes introducing temporary variables for the TRANSFER function;
>   this is better be handled by the middle-end.
> 
> Regression-tested.
> 
> OK for trunk?
> 
> 	Thomas
> 
> 2011-05-18  Thomas Koenig  <tkoenig@gcc.gnu.org>
> 
>         * frontend-passes.c (cfe_register_funcs):  Also register
>         character functions if their charlens are known and constant.
>         Also register allocatable functions.
> 
> 2011-05-18  Thomas Koenig  <tkoenig@gcc.gnu.org>
> 
>         * gfortran.dg/function_optimize_8.f90:  New test case.

OK.
Thomas Koenig May 22, 2011, 10:40 a.m. UTC | #2
Hi Steve,

>>          * frontend-passes.c (cfe_register_funcs):  Also register
>>          character functions if their charlens are known and constant.
>>          Also register allocatable functions.
>>
>> 2011-05-18  Thomas Koenig<tkoenig@gcc.gnu.org>
>>
>>          * gfortran.dg/function_optimize_8.f90:  New test case.
>
> OK.

Waiting for Emacs...
Sende          fortran/ChangeLog
Sende          fortran/frontend-passes.c
Sende          testsuite/ChangeLog
Hinzufügen     testsuite/gfortran.dg/function_optimize_8.f90
Übertrage Daten ....
Revision 174027 übertragen

Thanks a lot for the review!

	Thomas
diff mbox

Patch

Index: frontend-passes.c
===================================================================
--- frontend-passes.c	(Revision 173754)
+++ frontend-passes.c	(Arbeitskopie)
@@ -137,8 +137,7 @@  optimize_expr (gfc_expr **e, int *walk_subtrees AT
 
 
 /* Callback function for common function elimination, called from cfe_expr_0.
-   Put all eligible function expressions into expr_array.  We can't do
-   allocatable functions.  */
+   Put all eligible function expressions into expr_array.  */
 
 static int
 cfe_register_funcs (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED,
@@ -148,8 +147,10 @@  cfe_register_funcs (gfc_expr **e, int *walk_subtre
   if ((*e)->expr_type != EXPR_FUNCTION)
     return 0;
 
-  /* We don't do character functions (yet).  */
-  if ((*e)->ts.type == BT_CHARACTER)
+  /* We don't do character functions with unknown charlens.  */
+  if ((*e)->ts.type == BT_CHARACTER 
+      && ((*e)->ts.u.cl == NULL || (*e)->ts.u.cl->length == NULL
+	  || (*e)->ts.u.cl->length->expr_type != EXPR_CONSTANT))
     return 0;
 
   /* If we don't know the shape at compile time, we create an allocatable
@@ -163,9 +164,6 @@  cfe_register_funcs (gfc_expr **e, int *walk_subtre
      is specified.  */
   if ((*e)->value.function.esym)
     {
-      if ((*e)->value.function.esym->attr.allocatable)
-	return 0;
-
       /* Don't create an array temporary for elemental functions.  */
       if ((*e)->value.function.esym->attr.elemental && (*e)->rank > 0)
 	return 0;
@@ -181,9 +179,10 @@  cfe_register_funcs (gfc_expr **e, int *walk_subtre
   if ((*e)->value.function.isym)
     {
       /* Conversions are handled on the fly by the middle end,
-	 transpose during trans-* stages.  */
+	 transpose during trans-* stages and TRANSFER by the middle end.  */
       if ((*e)->value.function.isym->id == GFC_ISYM_CONVERSION
-	  || (*e)->value.function.isym->id == GFC_ISYM_TRANSPOSE)
+	  || (*e)->value.function.isym->id == GFC_ISYM_TRANSPOSE
+	  || (*e)->value.function.isym->id == GFC_ISYM_TRANSFER)
 	return 0;
 
       /* Don't create an array temporary for elemental functions,