This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: [Fortran] Conquering the last Frontier ... Help requested.
- To: gcc at gcc dot gnu dot org
- Subject: Re: [Fortran] Conquering the last Frontier ... Help requested.
- From: Toon Moene <toon at moene dot indiv dot nluug dot nl>
- Date: Mon, 22 Oct 2001 21:49:07 +0200
- Organization: Moene Computational Physics, Maartensdijk, The Netherlands
- References: <3BD2E14D.D08E5EA7@moene.indiv.nluug.nl>
Toon Moene wrote:
[ ... g77 probably rejects programs with >2**32 bit arrays on 32-bit
target unnecessarily ... ]
The Fortran front end rejects programs with arrays which are larger than
2**32 bits on 32-bit targets, i.e. arrays of more than 128M reals or 64M
double precision values. Apparently quite a few people are running into
this limitation - it is currently the question about g77 on
comp.lang.fortran with the highest occurrence.
I believe g77 is rejecting these programs unnecessarily.
<Theory>
Because all addressing of subobjects is done in bits in the GCC middle
end, g77 has to construct bit offsets when compiling array indices. On
32-bit targets, these indices cannot extend over more than 2**32 bits,
i.e. 2**29 bytes, that is one quarter or one eighth of the memory of
current high end IA32 machines.
However, all these bit-offsets-arising-from-array-indices have the form:
M * I / 8
on byte addressed machines (M the bitsize of the Fortran type, which
always is a multiple of 8). Because array index calculations are always
passed through fold(build(..)) before being handed to the middle end,
this would be simplified to (M/8)*I, which is representable in 32 bits,
even if I approaches 2**32 / (M/8).
IOW, it is not necessary to ensure that the bitsize is representable in
32 bits, only the byte size. The attached patch removes the extra
constraint.
</Theory>
Now for the help requested. Could someone with a > 1.2 Gbyte RAM 32-bit
machine test the following Fortran program ? I've run it for a value of
NSIZE of 5 000 000, but my machine is not large enough to successfully
run it for the value indicated below. Note that you have to link this
program statically (i.e. g77 -static) on GNU/Linux, as shared libraries
start at address 2**30 on this OS. Please try it with and without -O2
(i.e. loop optimisation). Thanks in advance !
PARAMETER (NSIZE = 100 000 000)
DIMENSION A(3*NSIZE), A1(NSIZE), A2(NSIZE), A3(NSIZE)
EQUIVALENCE (A( 1), A1(1))
EQUIVALENCE (A( NSIZE+1), A2(1))
EQUIVALENCE (A(2*NSIZE+1), A3(1))
DO I = 1, NSIZE
A1(I) = 0.0
A2(I) = 0.0
A3(I) = 0.0
ENDDO
DO I = 1, 3*NSIZE
A(I) = I
ENDDO
DO I = 1, NSIZE
IF (A1(I) .NE. A( I)) CALL ABORT
IF (A2(I) .NE. A( NSIZE+I)) CALL ABORT
IF (A3(I) .NE. A(2*NSIZE+I)) CALL ABORT
ENDDO
DO I = 1, NSIZE
A1(I) = 0.0
A2(I) = 0.0
A3(I) = 0.0
ENDDO
CALL SUB(A, 3*NSIZE)
DO I = 1, NSIZE
IF (A1(I) .NE. A( I)) CALL ABORT
IF (A2(I) .NE. A( NSIZE+I)) CALL ABORT
IF (A3(I) .NE. A(2*NSIZE+I)) CALL ABORT
ENDDO
END
SUBROUTINE SUB(A, N)
DIMENSION A(N)
DO I = 1, N
A(I) = I
ENDDO
END
This program "works" by virtue of the fact that the three arrays A1, A2
and A3 are smaller than the 2**32 bits mark, whereas the A array is
larger than this limit. If the addressing of A would be off, the
program would abort.
--
Toon Moene - mailto:toon@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)
2001-10-22 Toon Moene <toon@moene.indiv.nluug.nl>
* com.c (ffecom_check_size_overflow_): Only check for TREE_OVERFLOW.
*** com.c.orig Fri Oct 19 14:59:44 2001
--- com.c Sun Oct 21 14:17:15 2001
*************** ffecom_check_size_overflow_ (ffesymbol s
*** 2267,2272 ****
if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
! || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0))
! || TREE_OVERFLOW (TYPE_SIZE (type)))))
{
ffebad_start (FFEBAD_ARRAY_LARGE);
--- 2267,2271 ----
if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0)
! || (!dummy && TREE_OVERFLOW (TYPE_SIZE (type))))
{
ffebad_start (FFEBAD_ARRAY_LARGE);