[Patch] OpenMP/Fortran: Partially fix non-rect loop nests [PR107424]
Jakub Jelinek
jakub@redhat.com
Fri Jan 20 18:00:18 GMT 2023
On Fri, Jan 20, 2023 at 06:39:04PM +0100, Jakub Jelinek via Gcc-patches wrote:
> > + The issue is that for those a 'count' variable is used. */
> > + dovar_init *di;
> > + unsigned ix;
> > + tree t = tree_var;
> > + while (TREE_CODE (t) == INDIRECT_REF)
> > + t = TREE_OPERAND (t, 0);
> > + FOR_EACH_VEC_ELT (*inits, ix, di)
> > + {
> > + tree t2 = di->var;
> > + while (TREE_CODE (t2) == INDIRECT_REF)
> > + t2 = TREE_OPERAND (t2, 0);
>
> The actual problem with non-simple loops for non-rectangular loops is
> both in case it is an inner loop which uses some outer loop's iterator,
> or if it is outer loop whose iterator is used, both of those cases
> will not be handled properly. The former case because instead of
> having lb and ub expressions in canonicalized form var-outer * m + a
> lb will be 0 (that is fine) and ub will be
> (var-outer * m2 + a2 + step - var-outer * m1 - a1) / step
> or so (sure, we can simplify that to
> (var-outer * (m1 - m2) + (a2 + step - a1)) / step
> but the division remains. And the latter case is bad because we
> need var-outer but we actually compute some artificial count iterator
> and var-outer is only initialized in the body of the loop.
> These sorry_at seems to handle just one of those, when the outer
> loop whose var-outer is referenced is not simple, no?
Though, I wonder if we shouldn't for GCC 13 just sorry_at about
steps other than constant 1/-1 (in both outer loop with var-outer referenced
in inner loop and on inner loop that references it) and for the !VAR_P case
actually handle it if step 1/-1 by using simple like translation just with
an artificial iterator.
Say for:
subroutine foo (x, y, z)
integer :: x, y, z
!$omp do private (x)
do x = y, z
end do
end subroutine foo
we right now in *.original dump have:
D.4265 = *y;
D.4266 = *z;
D.4267 = (1 - D.4265) + D.4266;
#pragma omp for private(count.0) private(x)
for (count.0 = 0; count.0 < D.4267; count.0 = count.0 + 1)
{
*x = D.4265 + NON_LVALUE_EXPR <count.0>;
L.1:;
}
What I'd suggest is:
D.4265 = *y;
D.4266 = *z;
#pragma omp for private(x)
for (x.0 = D.4265; x.0 <= D.4266; x.0 = x.0 + 1)
{
*x = x.0;
L.1:;
}
or so. This could be done independently from the non-rect stuff,
as a first change.
Jakub
More information about the Gcc-patches
mailing list