Optimization of gfortran for execution speed
THOMAS Paul Richard 169137
prthomas@drfccad.cea.fr
Fri Oct 21 07:54:00 GMT 2005
Tobi,
> instead of being translated to a function call
> - don't forget to check that you don't break stuff like
> a(1:N-1) = a(2:N)
>
I cannot break it because it has not been fixed. Inspection of dependency.c
will convince you of that but in the meantime let the example below suffice.
For N variable, the dependency cannot be resolved but it works fine if it is
a constant.
What I am doing will permit this to work for cases like i(N-1:N) = i(N:N+1),
which is resolvable because the number of elements is constant.
Note also that the case mentioned by Dominique i(N:N+1) = i(N-1:N) produces
a temporary, even when N is a parameter. Again, examination of dependency.c
will show that there is no attempt made to treat this case. I would just as
soon leave it as a TODO until either I come to grips with how to reverse the
order of a scalarizer loop or one of the adepts intervenes. It would be easy
to signal a reverse dependency overlap, however.
I am beginning to wonder if some warnings might not be in order for cases
that cannot be treated, where a remedy can be effected by modification of
the source code?
Paul
integer, dimension(10) :: i = (/0,1,2,3,4,5,6,7,8,9/)
integer :: j, N = 6
do j = 1, 4
i(1:N) = i(2:N+1)
end do
end
produces the following code:-
MAIN__ ()
{
int4 j;
static int4 i[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static int4 n = 6;
j = 1;
if (j <= 4)
{
while (1)
{
{
logical4 D.575;
{
void * D.571;
int4 D.570;
struct array1_int4 atmp.0; /* <= Note the temporary. */
atmp.0.dtype = 265;
atmp.0.dim[0].stride = 1;
atmp.0.dim[0].lbound = 0;
atmp.0.dim[0].ubound = n - 1;
D.570 = NON_LVALUE_EXPR <n>;
D.571 = _gfortran_internal_malloc (D.570 * 4);
atmp.0.data = D.571;
atmp.0.offset = 0;
{
int4 S.1;
S.1 = 0;
while (1)
{
if (S.1 > n - 1) goto L.3; else (void) 0;
(*(int4[0:] *) atmp.0.data)[NON_LVALUE_EXPR <S.1>] =
i[NON_LVALUE_EXPR <S.1> + 1];
S.1 = S.1 + 1;
}
L.3:;
S.1 = 0;
while (1)
{
if (S.1 > n - 1) goto L.4; else (void) 0;
i[NON_LVALUE_EXPR <S.1>] = (*(int4[0:] *)
atmp.0.data)[NON_LVALUE_EXPR <S.1>];
S.1 = S.1 + 1;
}
L.4:;
}
_gfortran_internal_free (atmp.0.data);
}
L.1:;
D.575 = j == 4;
j = j + 1;
if (D.575) goto L.2; else (void) 0;
}
}
}
else
{
(void) 0;
}
L.2:;
}
changing N to a parameter gets rid of the temporary; thus:
MAIN__ ()
{
int4 j;
static int4 i[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
j = 1;
if (j <= 4)
{
while (1)
{
{
logical4 D.561;
{
int4 S.0;
S.0 = 1;
while (1)
{
if (S.0 > 6) goto L.3; else (void) 0;
i[NON_LVALUE_EXPR <S.0> + -1] = i[NON_LVALUE_EXPR <S.0>];
S.0 = S.0 + 1;
}
L.3:;
}
L.1:;
D.561 = j == 4;
j = j + 1;
if (D.561) goto L.2; else (void) 0;
}
}
}
else
{
(void) 0;
}
L.2:;
}
More information about the Fortran
mailing list