This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[fortran PATCH] Minor ALLOCATE translation improvements


Steve Kargl recently asked me to take a look at the following code...
On Mon, December 18, 2006 10:54 pm, Steve Kargl wrote:
> program v
>   real, allocatable :: x(:)
>   allocate(x(100))
>   x = 0.
> end program v
>
> This idiom appears in a few places in Polyhedron, and I know it
> is strewn throughout my own Fortran code.

The issue here is getting the array size propagated from the "allocate"
to the assignment such that it can be used in deciding which idiom to use.
It turns out that the generic that we currently generate for ALLOCATE is
already quite cryptic.

    if (0)
      {
        size.0 = 0;
      }
    else
      {
        size.0 = 400;
      }
    x.data = _gfortran_allocate64_array (x.data, size.0, 0);

The conditional is the result of the checks that no dimension in the
allocated array is negative.  Of course, for constants like in the example
code above, we know that's not the case so, the condition is always false.

Normally, cleaning up this tiny inefficiency wouldn't be worth the effort,
a small memory usage reduction, and reasonably left to the tree-ssa passes
to tidy up.  However, in trans-array.c, there are optimizations that take
advantage of knowing whether the array size is constant and what value it
has.  For example, the decision of whether a temporary array should be
allocated on the stack with alloca or on the heap with malloc.  In these
cases keeping track of "400" is preferrable to passing the variable "size.0".

The patch below therefore improves the initial generic we generate, when
the "or_expr" is known at compile-time.  In this case, we now get

  x.data = _gfortran_allocate64_array (x.data, 400, 0);


The following patch has been tested on x86_64-unknown-linux-gnu with a
full "make bootstrap", including gfortran, and tested with a top-level
"make -k check".

OK for mainline?

I'm still investigating approaches to optimizing Steve's example code
via memset, perhaps synthesizing __builtin_constant_p nodes.  However,
one alternative might be to support a __gfortran_clear_array function
in the libgfortran run-time, which at run-time can inspect the array
descriptor's stride, and make the appropriate intrinsic/libc calls or
implement the loops.  Effectively, outlining "x = 0" in these cases. 
Presumably, stride==1 is typical in real code/benchmarks, and we only call
this function if the array already has/needs a descriptor.  Thoughts?
Does anyone know what other F90/F95 compilers do?


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

        * trans-array.c (gfc_trans_create_temp_array): When the size is known
        at compile-time, avoid an unnecessary conditional assignment.
        (gfc_array_init_size): Likewise.

Roger
--

Attachment: patchf.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]