This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, update] PR25289 Large file IO
- From: Jerry DeLisle <jvdelisle at verizon dot net>
- To: Fortran List <fortran at gcc dot gnu dot org>, François-Xavier Coudert <fxcoudert at gmail dot com>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 22 Jul 2006 21:34:19 -0700
- Subject: [patch, update] PR25289 Large file IO
:REVIEWMAIL:
The attached patch is an update incorporating FX comments.
Bootstrapped and regression tested.
This patch defines a new type GFC_LARGE_IO_INT and uses that to define rec in
st_parameter_dt. off_t is preserved as is for the definition of gfc_offset.
OK for trunk?
Regards,
Jerry
2006-07-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/25289
* gfortran.h: Declare gfc_large_io_int_kind.
* trans-types.c (gfc_init_kinds): Set gfc_large_io_int_kind
to size 8 or 4.
* trans-io.c (enum iofield_type): Add large_io_int type.
(gfc_build_st_parameter): Same.
(gfc_build_io_library_fndecls): Same.
* ioparm_def: Use large_io_int to define rec.
2006-07-22 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libgfortran/25289
* libgfortran.h: Add conditional definition of GFC_LARGE_IO_INT type.
* io/io.h (st_parameter_dt): Define rec as type GFC_LARGE_IO_INT.
Index: gcc/fortran/gfortran.h
===================================================================
*** gcc/fortran/gfortran.h (revision 115683)
--- gcc/fortran/gfortran.h (working copy)
*************** extern int gfc_default_character_kind;
*** 1806,1811 ****
--- 1806,1812 ----
extern int gfc_default_logical_kind;
extern int gfc_default_complex_kind;
extern int gfc_c_int_kind;
+ extern int gfc_large_io_int_kind;
/* symbol.c */
void gfc_clear_new_implicit (void);
Index: gcc/fortran/trans-types.c
===================================================================
*** gcc/fortran/trans-types.c (revision 115683)
--- gcc/fortran/trans-types.c (working copy)
*************** int gfc_default_logical_kind;
*** 93,98 ****
--- 93,102 ----
int gfc_default_complex_kind;
int gfc_c_int_kind;
+ /* The kind size used for record offsets. If the target system supports
+ kind=8, this will be set to 8, otherwise it is set to 4. */
+ int gfc_large_io_int_kind;
+
/* Query the target to determine which machine modes are available for
computation. Choose KIND numbers for them. */
*************** gfc_init_kinds (void)
*** 140,145 ****
--- 144,157 ----
i_index += 1;
}
+ /* Set the kind used to match gfc_offset in libgfortran. This is used for
+ large file access. */
+
+ if (saw_i8)
+ gfc_large_io_int_kind = 8;
+ else
+ gfc_large_io_int_kind = 4;
+
/* Set the maximum integer kind. Used with at least BOZ constants. */
gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;
Index: gcc/fortran/trans-io.c
===================================================================
*** gcc/fortran/trans-io.c (revision 115683)
--- gcc/fortran/trans-io.c (working copy)
*************** enum ioparam_type
*** 52,57 ****
--- 52,58 ----
enum iofield_type
{
IOPARM_type_int4,
+ IOPARM_type_large_io_int,
IOPARM_type_pint4,
IOPARM_type_pchar,
IOPARM_type_parray,
*************** gfc_build_st_parameter (enum ioparam_typ
*** 168,173 ****
--- 169,175 ----
switch (p->type)
{
case IOPARM_type_int4:
+ case IOPARM_type_large_io_int:
case IOPARM_type_pint4:
case IOPARM_type_parray:
case IOPARM_type_pchar:
*************** void
*** 214,225 ****
--- 216,230 ----
gfc_build_io_library_fndecls (void)
{
tree types[IOPARM_type_num], pad_idx, gfc_int4_type_node;
+ tree gfc_large_io_int_type_node;
tree parm_type, dt_parm_type;
tree gfc_c_int_type_node;
HOST_WIDE_INT pad_size;
enum ioparam_type ptype;
types[IOPARM_type_int4] = gfc_int4_type_node = gfc_get_int_type (4);
+ types[IOPARM_type_large_io_int] = gfc_large_io_int_type_node
+ = gfc_get_int_type (gfc_large_io_int_kind);
types[IOPARM_type_pint4] = build_pointer_type (gfc_int4_type_node);
types[IOPARM_type_parray] = pchar_type_node;
types[IOPARM_type_pchar] = pchar_type_node;
Index: gcc/fortran/ioparm.def
===================================================================
*** gcc/fortran/ioparm.def (revision 115683)
--- gcc/fortran/ioparm.def (working copy)
*************** IOPARM (inquire, convert, 1 << 29,
*** 58,64 ****
#define IOPARM_dt_namelist_read_mode (1 << 8)
#endif
IOPARM (dt, common, 0, common)
! IOPARM (dt, rec, 1 << 9, int4)
IOPARM (dt, size, 1 << 10, pint4)
IOPARM (dt, iolength, 1 << 11, pint4)
IOPARM (dt, internal_unit_desc, 0, parray)
--- 58,64 ----
#define IOPARM_dt_namelist_read_mode (1 << 8)
#endif
IOPARM (dt, common, 0, common)
! IOPARM (dt, rec, 1 << 9, large_io_int)
IOPARM (dt, size, 1 << 10, pint4)
IOPARM (dt, iolength, 1 << 11, pint4)
IOPARM (dt, internal_unit_desc, 0, parray)
Index: libgfortran/libgfortran.h
===================================================================
*** libgfortran/libgfortran.h (revision 115683)
--- libgfortran/libgfortran.h (working copy)
*************** typedef off_t gfc_offset;
*** 196,201 ****
--- 196,211 ----
#include "kinds.h"
+ /* Define the type used for the current record number for large file I/O.
+ The size must be consistent with the size defined on the compiler side. */
+ #ifdef HAVE_GFC_INTEGER_8
+ typedef GFC_INTEGER_8 GFC_LARGE_IO_INT;
+ #else
+ #ifdef HAVE_GFC_INTEGER_4
+ typedef GFC_INTEGER_4 GFC_LARGE_IO_INT;
+ #endif
+ #endif
+
/* The following two definitions must be consistent with the types used
by the compiler. */
/* The type used of array indices, amongst other things. */
Index: libgfortran/io/io.h
===================================================================
*** libgfortran/io/io.h (revision 115683)
--- libgfortran/io/io.h (working copy)
*************** struct format_data;
*** 351,357 ****
typedef struct st_parameter_dt
{
st_parameter_common common;
! GFC_INTEGER_4 rec;
GFC_INTEGER_4 *size, *iolength;
gfc_array_char *internal_unit_desc;
CHARACTER1 (format);
--- 351,357 ----
typedef struct st_parameter_dt
{
st_parameter_common common;
! GFC_LARGE_IO_INT rec;
GFC_INTEGER_4 *size, *iolength;
gfc_array_char *internal_unit_desc;
CHARACTER1 (format);
!{ dg-do run }
!{ dg-options "-std=gnu" }
! PR25289 Cannot handle record numbers larger than huge(0_4).
! This test checks that very large record numbers can be used.
! Derived from example in PR.
! Submitted by Jerry DeLisle <jvdelisle@gcc.gnu.org>
integer*1 abyte
integer*8 n
n = huge(0_4)
n = n * 256
abyte = 105
open(10,file="foo",recl=2,form='unformatted',access='direct')
write(10,rec=n) abyte
abyte = 0
read(10,rec=n) abyte
if (abyte.ne.105) call abort()
write(10,rec=1) abyte
abyte = 0
read(10,rec=1) abyte
if (abyte.ne.105) call abort()
n=n/2
write(10,rec=n) abyte
abyte = 0
read(10,rec=n) abyte
if (abyte.ne.105) call abort()
close(10, status="delete")
end