public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch, fortran] Create some temporary variables for matmul arguments
@ 2017-05-28 21:47 Thomas Koenig
  2017-05-28 23:16 ` Jerry DeLisle
  0 siblings, 1 reply; 2+ messages in thread
From: Thomas Koenig @ 2017-05-28 21:47 UTC (permalink / raw)
  To: fortran, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 934 bytes --]

Hello world,

the attached patch generates some more opportunities for matmul inlining
by creating temporaries if arguments overlap, if the return is from
a function or something similar.

With this, we are pretty much coming to the end of the matmul
optimization saga.  After this, on to new shores! :-)

Regression-testing turned up a few problems, which were fixed
(see ChangeLog).

OK for trunk?

Regards

	Thomas

2017-05-28  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/37131
	* frontend-passes.c (check_conjg_transpose_variable):
	Add prototype.
	(has_dimen_vector_ref):  Likewise
	(matmul_temp_args):  New function. Add prototype.
	(optimize_namespace):  Call matmul_temp_args.

2017-05-28  Thomas Koenig  <tkoenig@gcc.gnu.org>

	PR fortran/37131
	* gfortran.dg/promotion_2.f90: Add -finline-matmul-limit=0 to
	flags.
	* gfortran.dg/transpose_optimization_1.f90: Likewise.
	* gfortran.dg/inline_matmul_17.f90:  New test.

[-- Attachment #2: p5.diff --]
[-- Type: text/x-patch, Size: 4535 bytes --]

Index: fortran/frontend-passes.c
===================================================================
--- fortran/frontend-passes.c	(Revision 248546)
+++ fortran/frontend-passes.c	(Arbeitskopie)
@@ -49,6 +49,10 @@ static int inline_matmul_assign (gfc_code **, int
 static gfc_code * create_do_loop (gfc_expr *, gfc_expr *, gfc_expr *,
 				  locus *, gfc_namespace *,
 				  char *vname=NULL);
+static gfc_expr* check_conjg_transpose_variable (gfc_expr *, bool *,
+						 bool *);
+static bool has_dimen_vector_ref (gfc_expr *);
+static int matmul_temp_args (gfc_code **, int *,void *data);
 
 #ifdef CHECKING_P
 static void check_locus (gfc_namespace *);
@@ -1087,11 +1091,13 @@ optimize_namespace (gfc_namespace *ns)
 			   (void *) &found);
 	}
       while (found);
-	
+
+      gfc_code_walker (&ns->code, matmul_temp_args, dummy_expr_callback,
+		       NULL);
       gfc_code_walker (&ns->code, inline_matmul_assign, dummy_expr_callback,
 		       NULL);
     }
-  
+
   /* BLOCKs are handled in the expression walker below.  */
   for (ns = ns->contained; ns; ns = ns->sibling)
     {
@@ -2157,6 +2163,92 @@ matmul_to_var_code (gfc_code **c, int *walk_subtre
 }
 
 
+/* Take a statement of the shape c = matmul(a,b) and create temporaries
+   for a and b if there is a dependency between the arguments and the
+   result variable or if a or b are the result of calculations that cannot
+   be handled by the inliner.  */
+
+static int
+matmul_temp_args (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
+		  void *data ATTRIBUTE_UNUSED)
+{
+  gfc_expr *expr1, *expr2;
+  gfc_code *co;
+  gfc_actual_arglist *a, *b;
+  bool a_tmp, b_tmp;
+  gfc_expr *matrix_a, *matrix_b;
+  bool conjg_a, conjg_b, transpose_a, transpose_b;
+  
+  co = *c;
+
+  if (co->op != EXEC_ASSIGN)
+    return 0;
+
+  if (forall_level > 0 || iterator_level > 0 || in_omp_workshare
+      || in_where)
+    return 0;
+
+  /* This has some duplication with inline_matmul_assign.  This
+     is because the creation of temporary variables could still fail,
+     and inline_matmul_assign still needs to be able to handle these
+     cases.  */
+  expr1 = co->expr1;
+  expr2 = co->expr2;
+
+  if (expr2->expr_type != EXPR_FUNCTION
+      || expr2->value.function.isym == NULL
+      || expr2->value.function.isym->id != GFC_ISYM_MATMUL)
+    return 0;
+
+  a_tmp = false;
+  a = expr2->value.function.actual;
+  matrix_a = check_conjg_transpose_variable (a->expr, &conjg_a, &transpose_a);
+  if (matrix_a != NULL)
+    {
+      if (matrix_a->expr_type == EXPR_VARIABLE
+	  && (gfc_check_dependency (matrix_a, expr1, true)
+	      || has_dimen_vector_ref (matrix_a)))
+	a_tmp = true;
+    }
+  else
+    a_tmp = true;
+
+  b_tmp = false;
+  b = a->next;
+  matrix_b = check_conjg_transpose_variable (b->expr, &conjg_b, &transpose_b);
+  if (matrix_b != NULL)
+    {
+      if (matrix_b->expr_type == EXPR_VARIABLE
+	  && (gfc_check_dependency (matrix_b, expr1, true)
+	      || has_dimen_vector_ref (matrix_b)))
+	b_tmp = true;
+    }
+  else
+    b_tmp = true;
+
+  if (!a_tmp && !b_tmp)
+    return 0;
+  
+  current_code = c;
+  inserted_block = NULL;
+  changed_statement = NULL;
+  if (a_tmp)
+    {
+      gfc_expr *at;
+      at = create_var (a->expr,"mma");
+      if (at)
+	a->expr = at;
+    }
+  if (b_tmp)
+    {
+      gfc_expr *bt;
+      bt = create_var (b->expr,"mmb");
+      if (bt)
+	b->expr = bt;
+    }
+  return 0;
+}
+
 /* Auxiliary function to build and simplify an array inquiry function.
    dim is zero-based.  */
 
Index: testsuite/gfortran.dg/promotion_2.f90
===================================================================
--- testsuite/gfortran.dg/promotion_2.f90	(Revision 248467)
+++ testsuite/gfortran.dg/promotion_2.f90	(Arbeitskopie)
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-fdefault-real-8 -fexternal-blas -fdump-tree-original" }
+! { dg-options "-fdefault-real-8 -fexternal-blas -fdump-tree-original -finline-matmul-limit=0" }
 !
 ! PR fortran/54463
 !
Index: testsuite/gfortran.dg/transpose_optimization_1.f90
===================================================================
--- testsuite/gfortran.dg/transpose_optimization_1.f90	(Revision 248467)
+++ testsuite/gfortran.dg/transpose_optimization_1.f90	(Arbeitskopie)
@@ -1,5 +1,5 @@
 ! { dg-do compile }
-! { dg-options "-Warray-temporaries -fdump-tree-original" }
+! { dg-options "-Warray-temporaries -fdump-tree-original -finline-matmul-limit=0" }
 !
 ! PR fortran/45648
 ! Non-copying descriptor transpose optimization (for function call args).

[-- Attachment #3: inline_matmul_17.f90 --]
[-- Type: text/x-fortran, Size: 1421 bytes --]

! { dg-do  run }
! { dg-options "-O -fdump-tree-optimized -finline-matmul-limit=1000" }
module x
  implicit none
contains
  function afunc()
    real, dimension(3,3) :: afunc
    afunc = reshape([ 2., 3., 5., 7., 11., 13., 17., 19., 23. ], [3,3])
  end function afunc
  
  function bfunc()
    real, dimension(3,3) :: bfunc
    bfunc = reshape([29., 31., 37., 41., 43., 47., 53., 59., 61., 67.],[3,3])
  end function bfunc
end module x

program main
  use x
  implicit none
  real, dimension(3,3), parameter :: &
       & aval = reshape([ 2., 3., 5., 7., 11., 13., 17., 19., 23. ], [3,3]), &
       & bval = reshape([29., 31., 37., 41., 43., 47., 53., 59., 61., 67.],[3,3])
  integer, dimension(3) :: ind
  real, dimension(3,3) :: a, b,c,d, ri
  data ri /120430., 187861., 151737., 161022., 251139., 202847., 212566., 331537., 267781./
  data d/904., 1131., 1399., 1182., 1489., 1845., 1556., 1967., 2435. /
  a = aval
  b = bval
  c = matmul(a,b)
  a = matmul(a,b)
  if (any(a-c /= 0)) call abort
  a = aval
  b = bval
  b = matmul(a,b)
  if (any(b-c /= 0)) call abort
  b = bval
  a = matmul(aval, b)
  if (any(a-c /= 0)) call abort
  ind = [1, 3, 2]
  c = matmul(a(ind,:),b)
  if (any(c-ri /= 0)) call abort
  c = matmul(afunc(),b)
  if (any(c-d /= 0)) call abort
  a = afunc()
  c = matmul(a, bfunc())
  if (any(c-d /= 0)) call abort
end program main
! { dg-final { scan-tree-dump-times "matmul_r4" 2 "optimized" } }

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [patch, fortran] Create some temporary variables for matmul arguments
  2017-05-28 21:47 [patch, fortran] Create some temporary variables for matmul arguments Thomas Koenig
@ 2017-05-28 23:16 ` Jerry DeLisle
  0 siblings, 0 replies; 2+ messages in thread
From: Jerry DeLisle @ 2017-05-28 23:16 UTC (permalink / raw)
  To: Thomas Koenig, fortran, gcc-patches

On 05/28/2017 02:40 PM, Thomas Koenig wrote:
> Hello world,
> 
> the attached patch generates some more opportunities for matmul inlining
> by creating temporaries if arguments overlap, if the return is from
> a function or something similar.
> 
> With this, we are pretty much coming to the end of the matmul
> optimization saga.  After this, on to new shores! :-)
> 
> Regression-testing turned up a few problems, which were fixed
> (see ChangeLog).
> 
> OK for trunk?
> 

OK, and thanks. I do think its time to move on. ;)

Jerry

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-05-28 22:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-28 21:47 [patch, fortran] Create some temporary variables for matmul arguments Thomas Koenig
2017-05-28 23:16 ` Jerry DeLisle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).