[PATCH] fortran/30207 -- Fix a WHERE and array section problem

roger@eyesopen.com roger@eyesopen.com
Fri Dec 15 05:27:00 GMT 2006


Hi Steve,

> That is,
>
>    integer :: z(4) = (/1,1,-1,-1/)
>    where (z < 0) z(:) = 1
>
> will lead to an ICE gfc_dep_resolver.  The short circuiting causes
> the allocation of temporary array to hold the mask from the z < 0
> conditional.
> ...
> There may be a better way to fix this problem.  Thus, the CC to
> Roger, who wrote gfc_dep_resolver.

I can't take credit for gfc_dep_resolver, but its not unlikely that
my major reorganization and improvements to that function have
probably triggered this problem.   The difficulty is that the dependency
analyzer needs to discover that z, z(:), z(1:4) and z(1:4:1) are all
effectively the same reference.  I suspect that I may have assumed that
the front-end canonicalized these array refs, and stepping through the
debugger it's clear the code doesn't expect a case in ARRAY_REF where
lref->u.ar.dimen != rref->u.ar.dimen, which can happen when one is an
AR_FULL and the other is an AR_SECTION.

The fix below is my proposed more aggresive fix to the problem.  It
starts by creating a new function gfc_full_array_ref_p, that can be
used to determine that an array section is equivalent to the full
array, i.e. it returns true for "z(:)", "z(1:4)", "z(::1)" etc...
This is then used in gfc_dep_resolver to allow us to compare apples
with oranges, such that if lref is simply "z" we test g_f_a_r_p in rref,
and vice versa.  Any other dimension mismatch is treated as a potential
dependency.  Finally, the new gfc_full_array_ref_p is exported, and
reused in trans-array.c's gfc_conv_expr_descriptor which requires a
similar test (and contains a comment that improved checking, as
implemented by this patch, is possible).

The following patch has been tested on x86_64-unknown-linux-gnu with
a "make bootstrap" including gfortran and tested with a "make
check-fortran" in the gcc/ subdirectory with no new failures.  This allows
Steve's new test case to compile (resolving the PR), but correctly
determines there's no dependency and generates far more efficient code.
Similarly, I tweaked the test case to use "z(1:4)" instead of "z", and
again the new routine did it's job, and we avoid the temporary array.

Ok for mainline?  My apologies for any potential e-mail problems; I'm
using a new mail client and this is my first attempt posting a patch
to gcc-patches/fortran with it.  Hopefully, the attachment will be fine,
but it seems to insist on wrapping my ChangeLog entry :-(



2006-12-14  Roger Sayle  <roger@eyesopen.com>

        PR fortran/30207
        * dependency.c (gfc_full_array_ref_p): New function to test whether
        the given array ref specifies the entire array.
        (gfc_dep_resolver): Use gfc_full_array_ref_p to analyze AR_FULL
        array refs against AR_SECTION array refs, and vice versa.
        * dependency.h (gfc_full_array_ref_p): Prototype here.
        * trans-array.c (gfc_conv_expr_descriptor):Use gfc_full_array_ref_p.

2006-12-14  Steven G. Kargl  <kargl@gcc.gnu.org>

        PR fortran/30207
        * gfortran.fortran-torture/execute/where21.f90: New test.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: patch.txt
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20061215/6abf1164/attachment.txt>


More information about the Gcc-patches mailing list