[Bug fortran/48419] [ABI cleanup] Reduce gfortran stack usage for procedures doing IO

jb at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Sep 19 08:01:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48419

--- Comment #9 from Janne Blomqvist <jb at gcc dot gnu.org> ---
Like Jerry said, we've recently had an ABI break (two, actually!), and I think
we should try hard to avoid yet another one.  I think it should be possible to
create some new st_parameter_dt_2 or such, as well as a new
data_transfer_init_2 entry point, and keep the old ones around for backwards
compatibility, rewriting data_transfer_init to wrap the new way of doing
things.

We can actually start with that, by moving private fields from st_parameter_dt
to gfc_unit. Or maybe make a separate per-data-transfer struct that is part of
gfc_unit, so that it can easily be memset() to 0 when starting a new data
transfer instead of having to separately touch every field.

I'm also thinking one way to speed up IO statements, if instead of memset()ing
said struct to zero, then go through every possible I/O specifier and set it to
the default value if missing etc., what if we had a few "ready-made" structs
(say one for formatted sequential, one for unformatted sequential, one for
unformatted direct etc.), and we just memcpy() the default struct. Then we'd
need to modify only the few fields that the flags variable say are present in
the I/O statement. But this can be done later.

Finally, for the new ABI entry points to save stack space, if for
data_transfer_init_2 we adopt approach b) that I described in the first message
in this PR, the st_parameter_dt_2 struct need to only contain the pointer to
the gfc_unit structure, and maybe a few other things.

That is, what the frontend passes is the unit number (that can be handled
separately since it's always present), the flags variable, the
st_parameter_dt_2 struct which contains the pointer to the gfc_unit struct (and
maybe a few other fields?), and a pointer to an array (that the frontend
creates on the stack prior to calling data_transfer_init_2) with elements

union dt_elem {
    void* ptr;
    int   c_int;
    size_t  usize;
    ptrdiff_t isize;
    GFC_IO_INT  io_int;
}

and then popcount(flags) would tell the number of elements in the array, except
for character arguments which would take two elements, one for the pointer to
the string and another for the length. And the order of the elements in the
array would be determined by the flags argument.


More information about the Gcc-bugs mailing list