Discussion:
Target control of Fortran options
Paul Koning
2018-10-03 21:04:51 UTC
Permalink
In the C and C++ parts of GCC, the target has some ways to adjust the compiler options depending on target settings. I'm looking for a way to do that with gfortran.

The specific issue is in pdp11, which has an option to specify that "float" is 8 bytes (same as "double") rather than 4 bytes. And the 8 byte choice is the default.

As a result, if I invoke gfortran for that target, I get an ICE because real*4 can't be found. If I say -fdefault-real-8 it works.

So what I'm hoping to do is to have the target switch processing code (for the TARGET_HANDLE_OPTION hook) react to the -mfloat32 and -mfloat64 switches by passing appropriate -fdefault-real-* switches to Fortran. Is that possible?

paul
Richard Biener
2018-10-04 08:06:02 UTC
Permalink
Post by Paul Koning
In the C and C++ parts of GCC, the target has some ways to adjust the compiler options depending on target settings. I'm looking for a way to do that with gfortran.
The specific issue is in pdp11, which has an option to specify that "float" is 8 bytes (same as "double") rather than 4 bytes. And the 8 byte choice is the default.
As a result, if I invoke gfortran for that target, I get an ICE because real*4 can't be found. If I say -fdefault-real-8 it works.
So what I'm hoping to do is to have the target switch processing code (for the TARGET_HANDLE_OPTION hook) react to the -mfloat32 and -mfloat64 switches by passing appropriate -fdefault-real-* switches to Fortran. Is that possible?
I think Fortran has to do it the same way the C family does.
float/double get assigned
by looking at FLOAT_TYPE_SIZE / [LONG_]DOUBLE_TYPE_SIZE. Iff that's not good
for the Fortran FE we'd have to define additional target hooks the FE can use.

Richard.
Post by Paul Koning
paul
Paul Koning
2018-10-04 14:04:32 UTC
Permalink
Post by Richard Biener
Post by Paul Koning
In the C and C++ parts of GCC, the target has some ways to adjust the compiler options depending on target settings. I'm looking for a way to do that with gfortran.
The specific issue is in pdp11, which has an option to specify that "float" is 8 bytes (same as "double") rather than 4 bytes. And the 8 byte choice is the default.
As a result, if I invoke gfortran for that target, I get an ICE because real*4 can't be found. If I say -fdefault-real-8 it works.
So what I'm hoping to do is to have the target switch processing code (for the TARGET_HANDLE_OPTION hook) react to the -mfloat32 and -mfloat64 switches by passing appropriate -fdefault-real-* switches to Fortran. Is that possible?
I think Fortran has to do it the same way the C family does.
float/double get assigned
by looking at FLOAT_TYPE_SIZE / [LONG_]DOUBLE_TYPE_SIZE. Iff that's not good
for the Fortran FE we'd have to define additional target hooks the FE can use.
It appears that Fortran has a different approach. Fortran has syntax like "REAL*8" to request a float of a specific size. And what gfortran does is assume that "REAL" without a size specifier means "REAL*n" for a well known fixed n. Without switches, n is 4, which is indeed the common answer. But in my case, there isn't any 4-byte float type unless you say -mfloat32.

Maybe the answer is "that's a wrong thing to do". If so, I suppose I could change it -- it was done before I got involved and I don't know for what reason.

paul
N.M. Maclaren
2018-10-04 15:41:21 UTC
Permalink
It appears that Fortran has a different approach. Fortran has syntax like
"REAL*8" to request a float of a specific size. And what gfortran does is
assume that "REAL" without a size specifier means "REAL*n" for a well
known fixed n. Without switches, n is 4, which is indeed the common
answer. But in my case, there isn't any 4-byte float type unless you say
-mfloat32.
If you don't have a 4-byte REAL, why do you make default REAL 4 bytes?
Do you mean that the front-end code assumes that it is? In which case,
I would say that it's a clear design bug! If not, why not just set it to
your basic floating type?

It's commonly 8 bytes on machines where that is the basic real size (e.g.
Cray vector systems); I don't know if gfortran supports any such systems,
but that's the approach that is universally taken for them. In fact,
mapping REAL*4 to 8 bytes is quite common with precision-extension options
in some compilers, and your implementation sounds similar.

I assume that you know that REAL*n isn't a standard Fortran facility, and
the "n" isn't always the size in bytes. For the standard equivalent,
what does your version map REAL(SELECTED_REAL_SIZE(6)) to?


Regards,
Nick Maclaren.
Paul Koning
2018-10-04 15:48:27 UTC
Permalink
Post by N.M. Maclaren
It appears that Fortran has a different approach. Fortran has syntax like "REAL*8" to request a float of a specific size. And what gfortran does is assume that "REAL" without a size specifier means "REAL*n" for a well known fixed n. Without switches, n is 4, which is indeed the common answer. But in my case, there isn't any 4-byte float type unless you say -mfloat32.
If you don't have a 4-byte REAL, why do you make default REAL 4 bytes?
Do you mean that the front-end code assumes that it is? In which case,
I would say that it's a clear design bug! If not, why not just set it to
your basic floating type?
That's what I expected and apparently I'm not the only one. But the actual code says that the default REAL is the 4 byte one, and if the compiler doesn't supply a float type of that size, the compiler crashes at startup.

Janne raises an interesting point, about Fortran requirements of int and float and double sizes that I was not aware of. Given those, it seems that the correct answer is to do the more traditional thing where "float" (REAL) is SFmode, 4 bytes -- always. In other words, make -mfloat32 be the only operating mode and retire that switch.

paul
N.M. Maclaren
2018-10-04 16:20:52 UTC
Permalink
Post by N.M. Maclaren
If you don't have a 4-byte REAL, why do you make default REAL 4 bytes?
Do you mean that the front-end code assumes that it is? In which case,
I would say that it's a clear design bug! If not, why not just set it to
your basic floating type?
That's what I expected and apparently I'm not the only one. But the
actual code says that the default REAL is the 4 byte one, and if the
compiler doesn't supply a float type of that size, the compiler crashes
at startup.
That's a design mistake, though I can see how it happened. You do mean
4 byte, and not just REAL*4, though? If the latter, you can just make
REAL*4 mean your default real and have done with it! As I said, that
number is not always the size in bytes :-)
Janne raises an interesting point, about Fortran requirements of int and
float and double sizes that I was not aware of. Given those, it seems
that the correct answer is to do the more traditional thing where "float"
(REAL) is SFmode, 4 bytes -- always. In other words, make -mfloat32 be
the only operating mode and retire that switch.
Not necessarily. Another option is to simply pad default INTEGER and
DOUBLE PRECISION - that's a common solution, and fully conforming. But
I don't know how hard that would be to do.

It's not relevant to the PDP11, but a lot of people feel that the correct
defaults for the modern world are 8 byte default integer and real, and
16 byte double precision.


Regards,
Nick Maclaren.
Paul Koning
2018-10-04 18:51:54 UTC
Permalink
...
Yes. There are, however, some complications here. Namely that the Fortran standard specifies that REAL, INTEGER, and LOGICAL types of default kind must all be the same size. And furthermore, there must exist a type DOUBLE PRECISION which is twice the size of the default kind REAL.
So what this implies is that e.g. if you want the default kind REAL to be 8 bytes, then the default kind INTEGER and LOGICAL must also be 8 bytes types, and further there must exist a 16 byte DOUBLE PRECISION type.
Thanks, that was very helpful. While pdp11 can do INTEGER*8, it can't do REAL*16. And I have no idea why the float == double thing was done originally in the first place. It goes all the way back to the original version of the file (from 1994).

I've decided to yank that option, so FLOAT_SIZE is 32 always (and DOUBLE_SIZE is 64 as it was all along). That seems more intuitive anyway for people familiar with that target.

paul
N.M. Maclaren
2018-10-05 08:44:01 UTC
Permalink
On Oct 4, 2018, at 10:31 AM, Janne Blomqvist
So what this implies is that e.g. if you want the default kind REAL to
be 8 bytes, then the default kind INTEGER and LOGICAL must also be 8
bytes types, and further there must exist a 16 byte DOUBLE PRECISION
type.
Thanks, that was very helpful. While pdp11 can do INTEGER*8, it can't do
REAL*16. And I have no idea why the float == double thing was done
originally in the first place. It goes all the way back to the original
version of the file (from 1994).
The requirement is on storage size, not extra precision or range. As I
tried to say earlier, but may not have been clear, the usual solution to
that issue was to have DOUBLE PRECISION using an 8-byte real in a 16-byte
location - i.e. 8 bytes of data and 8 of padding, on some order.

It does seem a bit odd, though there are several plausible reasons.


Regards,
Nick Maclaren.

Loading...