This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, fortran] Trim spaces on list-directed reads
- From: Thomas Koenig <tkoenig at netcologne dot de>
- To: "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 10 Apr 2012 14:32:23 +0200
- Subject: [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)