On Wed, Aug 1, 2012 at 2:37 PM, Tobias Burnus <bur...@net-b.de> wrote: > 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.]
Well, I wouldn't concentrate on this one ;) > 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.) c) Do _not_ fold everything to rank-1 arrays (this makes data dependence analysis harder). If you know the rank of an array use an intermediate array pointer type to access the data, like the following C example: void foo (void *data, int n, int m) { int (*a)[n][m] = (int (*)[n][m]) data; int i, j; for (i = 0; i < n; ++i) for (j = 0; j < m; ++j) (*a)[i][j] = 0; } d) Think about Frontend optimizations again - using the ISL part of GRAPHITE on the GFortran IL, possibly driving the scalarizer with the result. Richard. > Tobias