[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