[Patch, Fortran] assumed-rank some bound intrinsics support, fix failures and improve diagnostcs

Tobias Burnus burnus@net-b.de
Wed Aug 1 12:38:00 GMT 2012


On 08/01/2012 01:37 PM, Mikael Morin wrote:
>> However, I found another spot where one needs to have a scalarizer;
>> possibly a poor man's version is enough. Namely INTENT(OUT) handling.
> Indeed.
>> Do you have an idea how to best handle that case?
> It seems some new code is necessary. I don't know how well it will
> fit/reuse the existing though.

I think we should try to get this working in some way for 4.8 as 
assumed-rank arrays will be used for the finalization wrapper - and it 
would be awesome to have FINAL support in 4.8.

Background: As it is unknown (at compile time) whether a polymorphic 
variable has no final subroutines or one for that rank or an elemental 
one (or some but no suitable ones) - and as there could be a different 
combination for the parent type, the current plan is to add a _final 
proc-pointer to the vtable, which points to a final wrapper procedure 
for that type. It takes (at least for arrays) an assumed-rank array and 
dispatches the calls based on the rank; for an elemental final 
subroutine, it has to "scalarize it". [It's simple to add a special case 
as the array is contiguous - one just needs to "call 
elemental(base_address + i*elem_size)", where i = 
1,size(assumed-size-array).]

And for finalization, it would be great if one could use the INTENT(OUT) 
support. One could alternatively implement it manually on the gfortran 
AST level (gfc_code/gfc_expr) by walking through the derived type or one 
could implement a simplified version, making use of the contiguity of 
the finalized variable.


> I have been thinking about rewriting the scalarizer in a way that would
> need less bookkeeping to make things work. Nothing near a patch though,
> and it's not something for 4.8.

I think it would be good to base it on the new array descriptor, which 
we hopefully have by that time. Additionally, we should consider to support:

a) ARRAY_RANGE_REF: That's probably somewhat independent of 
scalarization, but replaces it in some cases:
   A(:,:,5) = B(:)
can be implemented as ARRAY_RANGE_REF, if the memory is contiguous; one 
just passes an offset and (via the decl) the size of the array 
(section). See trans-expr.c for one example. A range ref is better than 
a memcpy/memmove or a loop - as the first looses the data type and some 
alias information and the second represents the structure in a more 
convoluted way. Either could be recovered by the middle end, but it 
currently isn't and doing it correctly from the beginning makes the ME 
life easier.

b) Middle-end arrays. Richard made an initial patch, cf. 
http://gcc.gnu.org/wiki/GCCGathering2011Fortran . It probably needs some 
polishing and some optimizations have to be implemented, but then it 
should work and allow for further optimizations. [Description in the 
wiki might be partially wrong; blame me - and correct it, if you find 
something.]

I think the latter requires also some thinking about how to handle 
arrays internally: In that case, the array has - at least for the 
scalarization - more than one rank (for the ME) while gfortran normally 
folds everything to rank-1 arrays. Additionally, one needs to think 
about the case where the array has nonunit strides, i.e. where the 
leftmost stride is not sizeof(declared type) but larger by a noninteger 
amount. (e.g. passing a polymorphic array to a TYPE.)

Tobias



More information about the Fortran mailing list