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] Trim spaces on list-directed reads


Hello world,

this patch effectively trims the spaces from the string on
list-directed reads.  This avoids the large overhead on
processing these spaces when reading from long lines.

I didn't do this for internal units which are arrays because
this would need a separate calculation for each record, and
would mean a major change to the way the code is structured.

The running time for the test case from PR 50673 is reduced
from ~8 s to 0.1 s by this patch.

Regression-tested. OK for trunk?

Thomas

2012-04-09 Thomas Koenig <tkoenig@gcc.gnu.org>

        PR libfortran/38199
        PR libfortran/50673
        * intrinsics/string_intriniscs_inc.c (string_len_trim):
        Remove prototypes for string_len_trim and move to...
        * libgfortran.h (string_len_trim): ... here and
        (string_len_trim_char4): ...here.
        * io/unit.c: For non-array internal arrays where we do reading,
        adjust the record length to the last non-blank character.
        * io/unix.c:  Fix typo.
Index: intrinsics/string_intrinsics_inc.c
===================================================================
--- intrinsics/string_intrinsics_inc.c	(Revision 186190)
+++ intrinsics/string_intrinsics_inc.c	(Arbeitskopie)
@@ -44,9 +44,6 @@ extern void concat_string (gfc_charlen_type, CHART
 			   gfc_charlen_type, const CHARTYPE *);
 export_proto(concat_string);
 
-extern gfc_charlen_type string_len_trim (gfc_charlen_type, const CHARTYPE *);
-export_proto(string_len_trim);
-
 extern void adjustl (CHARTYPE *, gfc_charlen_type, const CHARTYPE *);
 export_proto(adjustl);
 
Index: libgfortran.h
===================================================================
--- libgfortran.h	(Revision 186190)
+++ libgfortran.h	(Arbeitskopie)
@@ -791,6 +791,13 @@ internal_proto(fstrcpy);
 extern gfc_charlen_type cf_strcpy (char *, gfc_charlen_type, const char *);
 internal_proto(cf_strcpy);
 
+extern gfc_charlen_type string_len_trim (gfc_charlen_type, const char *);
+export_proto(string_len_trim);
+
+extern gfc_charlen_type string_len_trim_char4 (gfc_charlen_type,
+					       const gfc_char4_t *);
+export_proto(string_len_trim_char4);
+
 /* io/intrinsics.c */
 
 extern void flush_all_units (void);
Index: io/unit.c
===================================================================
--- io/unit.c	(Revision 186190)
+++ io/unit.c	(Arbeitskopie)
@@ -397,7 +397,7 @@ get_internal_unit (st_parameter_dt *dtp)
   __gthread_mutex_lock (&iunit->lock);
 
   iunit->recl = dtp->internal_unit_len;
-  
+
   /* For internal units we set the unit number to -1.
      Otherwise internal units can be mistaken for a pre-connected unit or
      some other file I/O unit.  */
@@ -415,6 +415,26 @@ get_internal_unit (st_parameter_dt *dtp)
 
       start_record *= iunit->recl;
     }
+  else
+    {
+      /* If we are not processing an array, adjust the unit record length not
+	 to include trailing blanks for list-formatted reads.  */
+      if (dtp->u.p.mode == READING && dtp->format == NULL)
+	{
+	  if (dtp->common.unit == 0)
+	    {
+	      dtp->internal_unit_len =
+		string_len_trim (dtp->internal_unit_len, dtp->internal_unit);
+	      iunit->recl = dtp->internal_unit_len;
+	    }
+	  else
+	    {
+	      dtp->internal_unit_len =
+		string_len_trim_char4 (dtp->internal_unit_len, dtp->internal_unit);
+	      iunit->recl = dtp->internal_unit_len;
+	    }
+	}
+    }
 
   /* Set initial values for unit parameters.  */
   if (dtp->common.unit)
Index: io/unix.c
===================================================================
--- io/unix.c	(Revision 186190)
+++ io/unix.c	(Arbeitskopie)
@@ -736,7 +736,7 @@ mem_alloc_w4 (stream * strm, int * len)
 }
 
 
-/* Stream read function for character(kine=1) internal units.  */
+/* Stream read function for character(kind=1) internal units.  */
 
 static ssize_t
 mem_read (stream * s, void * buf, ssize_t nbytes)

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