This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, Fortran] PR56907 - do not 'pack' arrays passed to C_LOC


Fortran 2008 supports C_LOC(array); if the argument is not simply contiguous, the current code adds a call to __gfortran_intrinsic_pack.

The pack call shouldn't be there. Fortran 2008 demands that the actual argument is contiguous and intrinsic_pack copy creates a copy if the run-time check shows that the argument is not contiguous. Thus, it is not a wrong-code issue. However, for performance reasons, it makes sense to avoid the call __gfortran_intrinsic_pack.

Build and regtested on x86-64-gnu-linux.
OK for the trunk?

Tobias
2013-04-10  Tobias Burnus  <burnus@net-b.de>

	PR fortran/56907
	* trans-intrinsic.c (conv_isocbinding_function): Don't pack array
	passed to C_LOC

2013-04-10  Tobias Burnus  <burnus@net-b.de>

	PR fortran/56907
	* gfortran.dg/c_loc_test_22.f90: New.

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 9b2cc19..005dd73 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -6317,8 +6317,13 @@ conv_isocbinding_function (gfc_se *se, gfc_expr *expr)
     {
       if (arg->expr->rank == 0)
 	gfc_conv_expr_reference (se, arg->expr);
-      else
+      else if (gfc_is_simply_contiguous (arg->expr, false))
 	gfc_conv_array_parameter (se, arg->expr, true, NULL, NULL, NULL);
+      else
+	{
+	  gfc_conv_expr_descriptor (se, arg->expr);
+	  se->expr = gfc_conv_descriptor_data_get (se->expr);
+	}
 
       /* TODO -- the following two lines shouldn't be necessary, but if
 	 they're removed, a bug is exposed later in the code path.
--- /dev/null	2013-04-10 09:49:18.320086712 +0200
+++ gcc/gcc/testsuite/gfortran.dg/c_loc_test_22.f90	2013-04-10 21:42:20.835284814 +0200
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR fortran/56907
+!
+subroutine sub(xxx, yyy)
+  use iso_c_binding
+  implicit none
+  integer, target, contiguous :: xxx(:)
+  integer, target             :: yyy(:)
+  type(c_ptr) :: ptr1, ptr2, ptr3, ptr4
+  ptr1 = c_loc (xxx)
+  ptr2 = c_loc (xxx(5:))
+  ptr3 = c_loc (yyy)
+  ptr4 = c_loc (yyy(5:))
+end
+! { dg-final { scan-tree-dump-not " _gfortran_internal_pack" "original" } }
+! { dg-final { scan-tree-dump-times "parm.\[0-9\]+.data = \\(void .\\) &\\(.xxx.\[0-9\]+\\)\\\[0\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "parm.\[0-9\]+.data = \\(void .\\) &\\(.xxx.\[0-9\]+\\)\\\[D.\[0-9\]+ \\* 4\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "parm.\[0-9\]+.data = \\(void .\\) &\\(.yyy.\[0-9\]+\\)\\\[0\\\];" 1 "original" } }
+! { dg-final { scan-tree-dump-times "parm.\[0-9\]+.data = \\(void .\\) &\\(.yyy.\[0-9\]+\\)\\\[D.\[0-9\]+ \\* 4\\\];" 1 "original" } }
+
+! { dg-final { scan-tree-dump-times "D.\[0-9\]+ = parm.\[0-9\]+.data;\[^;]+ptr\[1-4\] = D.\[0-9\]+;" 4 "original" } }
+! { dg-final { cleanup-tree-dump "optimized" } }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]