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]

Update: [patch, libfortran] Fix EOF handling in array I/O


Here's an update to the previous patch.

Upon reflection, I think it is better for performance to have two
versions of the loop so the test is only performed when it is
needed.

So, OK for trunk?

Regards

	Thomas

Fix EOF handling for arrays.

2019-11-23  Thomas Koenig  <tkoenig@gcc.gnu.org>
        Harald Anlauf <anlauf@gmx.de>

        PR fortran/92569
        * io/transfer.c (transfer_array_inner):  If position is
        at AFTER_ENDFILE in current unit, return from data loop.

2019-11-23  Thomas Koenig  <tkoenig@gcc.gnu.org>
        Harald Anlauf <anlauf@gmx.de>

        PR fortran/92569
        * gfortran.dg/eof_4.f90: New test.

Index: io/transfer.c
===================================================================
--- io/transfer.c	(Revision 278025)
+++ io/transfer.c	(Arbeitskopie)
@@ -2542,26 +2542,62 @@ transfer_array_inner (st_parameter_dt *dtp, gfc_ar
 
   data = GFC_DESCRIPTOR_DATA (desc);
 
-  while (data)
+  /* When reading, we need to check endfile conditions so we do not miss
+     an END=label.  Make this separate so we do not have an extra test
+     in a tight loop when it is not needed.  */
+
+  if (dtp->u.p.current_unit && dtp->u.p.mode == READING)
     {
-      dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
-      data += stride0 * tsize;
-      count[0] += tsize;
-      n = 0;
-      while (count[n] == extent[n])
+      while (data)
 	{
-	  count[n] = 0;
-	  data -= stride[n] * extent[n];
-	  n++;
-	  if (n == rank)
+	  if (unlikely (dtp->u.p.current_unit->endfile == AFTER_ENDFILE))
+	    return;
+
+	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
+	  data += stride0 * tsize;
+	  count[0] += tsize;
+	  n = 0;
+	  while (count[n] == extent[n])
 	    {
-	      data = NULL;
-	      break;
+	      count[n] = 0;
+	      data -= stride[n] * extent[n];
+	      n++;
+	      if (n == rank)
+		{
+		  data = NULL;
+		  break;
+		}
+	      else
+		{
+		  count[n]++;
+		  data += stride[n];
+		}
 	    }
-	  else
+	}
+    }
+  else
+    {
+      while (data)
+	{
+	  dtp->u.p.transfer (dtp, iotype, data, kind, size, tsize);
+	  data += stride0 * tsize;
+	  count[0] += tsize;
+	  n = 0;
+	  while (count[n] == extent[n])
 	    {
-	      count[n]++;
-	      data += stride[n];
+	      count[n] = 0;
+	      data -= stride[n] * extent[n];
+	      n++;
+	      if (n == rank)
+		{
+		  data = NULL;
+		  break;
+		}
+	      else
+		{
+		  count[n]++;
+		  data += stride[n];
+		}
 	    }
 	}
     }
! { dg-do run }
! { dg-options "-ffrontend-optimize" }
! PR 92569 - the EOF condition was not recognized with
! -ffrontend-optimize.  Originjal test case by Bill Lipa.
program main
  implicit none
  real(kind=8) ::  tdat(1000,10)
  real(kind=8) :: res (10, 3)
  integer :: i, j, k, np

  open (unit=20, status="scratch")
  res = reshape([(real(i),i=1,30)], shape(res))
  write (20,'(10G12.5)') res
  rewind 20
  do  j = 1,1000
     read (20,*,end=1)(tdat(j,k),k=1,10)
  end do
      
1 continue
  np = j-1
  if (np /= 3) stop 1
  if (any(transpose(res) /= tdat(1:np,:))) stop 2
end program main

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