This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

Re: Finalization and automatic deallocation


Paul Richard Thomas wrote:
I am sorry to have left you, Janus and Tobias in the lurch these last
weeks - I have just returned from a trip.  I'll try to catch up over
the next few days.

You're welcome, no problem!


What I'm thinking of in more detail:  Port the gfc_finalize_expr & friends
to working on trees together with gfc_symbol's representing their original
derived-type rather than gfc_expr's so those can be used from trans; if this
is ok, I'm also thinking of adding a new gfortran-internal statement-type

The allocatable components finalization wound up in trans-array.c because it would up to be so much more convenient there. If I had thought about nested finalizable derived types, I might well have suggested following the same route.

Yeah, I already found that. But (at the moment) I don't think that would be the best place to do finalization of those components before they are deallocated. (Actually, I did already implement basic finalization before auto-deallocation during trans; but then I found out that it will be needed for far more places and now think it's not feasible to do it like that.) See below.


Just another thought:  What do you think about moving auto-deallocation
logic from trans to resolution?  I think it should be very much the same
like finalization to generate EXEC_DEALLOCATE statements there at the needed
places.  And doing so could allow us to keep finalization in resolution
phase and still have no duplication.  It could even be easier to do
auto-deallocation there.

I think that you'll have to explain what you mean here. Maybe I'm tired:) but I don't understand what you are proposing.

Ok, I'll try again: Everything done so far for finalization (which I believe is close to finishing, only a few parts missing; but those might be the most difficult ones...) is in resolution and it works quite well there, as you foretelled yourself correctly :)


The only thing that's bugging me is that to finalize all those ALLOCATABLE entities before they are auto-deallocated during resolution, I have to somehow "duplicate" the code used in auto-deallocation as I have to find the exact same places and insert finalizer-calls there; after some thoughts and started coding yesterday, I now believe this will be possible rather easily. But my point is, I don't like the idea of *duplicating* this logic so we have to keep sync between where things are deallocated in trans and finalized in resolution.

So my proposal is, once finalization is working with this duplication, to try to remove auto-deallocation logic from trans and simply add EXEC_DEALLOCATE statements to the tree during resolution after those finalizer-calls inserted where auto-deallocation happens. If I get everything right for finalization, it should be a minor effort to additionally add those EXEC_DEALLOCATE statements after the finalization code, but it will enable us to get rid of the whole auto-deallocation during trans, because there we only need to translate EXEC_DEALLOCATE where it is in the tree and we can rely on it being everywhere where it is needed, being it explicitelly in the code or because of an auto-deallocation.

I hope I got it somehow not confusing this time... In any case, if you agree I can try finishing finalization during resolution and try to insert finalizer-calls there at places where auto-deallocation should happen independently from the auto-deallocation logic in trans, I will do this. And then I can try to get this move auto-deallocation from trans to resolution done and we can then decide if the patch looks good or we leave it alone.

It's just that after I heard about auto-deallocation and where it happens (something goes out of scope, giving ALLOCATABLE entity to INTENT(OUT)) I realized it's closely connected to finalization. Both are there to prevent memory-leaks and thus must have something in common, and finalization must happen at every place where auto-deallocation happens (IIRC). So why not share those two in the same code?

After some more thoughts I think that finalization is really done easier in
resolution because much information needed (beyond the derived-type an
expression is of) will not (or I don't think it will) available in trans,
like expression rank (or is it available from a raw tree).

The information that you talk about is not exclusive to resolution - take a look at structure_alloc_comps and the subsequent primitives for the API. Erik and I worked hard to make that work. I had hoped that doing the business in resolve.c might be more transparent.

Ah, ok; then that will be a second option if my current plan finally fails :D But I think I'll need some start on this, as I'm currently not really familiar with trans in itself and what's there...


If I find time, I'll try to finish finalization as described above; but I'd
be happy to hear your comments as I'm not really aware of most the details
of gfortran...

I'm not exactly sure that any of us are anymore! I have become convinced that we must start breaking out the F03/F08 parts into new source files to simplify the job of keeping track of things.

Well, sometimes I'm quite surprised on how long some methods in the code are (gfc_conv_function_call or how it's called being the example I'm thinking of). But I don't think this is a problem with F03/F08 in itself but rather generally. Maybe we should try to split some of the longer methods into seperate parts; if I find some time in the future and a long function I'm aware of what it does, I can try to do some work here myself.


Regarding F03/F08 features, I can only tell about array constructors with typespec, structure constructor syntax and now finalization. The first one was probably a rather "minor" new feature and nothing that could be done seperately, I think; it was mainly some small changes to some pieces of the code.

Structure constructors was mainly about extending gfc_match_structure_constructor and nearly all work was done there, so I don't think we should have split-off this now larger function into a new source-file as it's still just gfc_match_structure_constructor and no new "unit" in itself.

I'd argue the same is true for finalization, it's just mainly some new functions to do the work and some changes in gfc_resolve_code (and others) to intiate this process. But here I think it would make some sense to move the main finalization-functions (gfc_finalize_expr and the derived-components methods used by it) from expr.c to a new hypothetical oop.c or other source-file that could deal with F03/F08 object-orientation (for instance). But that's up to you, I don't find large source-files in any way a comparable problem to large functions; although in my own (C++) projects I used to keep nearly every class seperated and thus had files around 500 SLOC on average or so, compared to 5000 for an average gfortran .c file (just guessed).

Well, I'm going back to the code this afternoon (I've some lectures now), after I managed to get the DO-loop built for scalarization, I'm now struggling with an IF-block :D But I'll get it. Hopefully...

Yours,
Daniel

--
Done:     Bar-Sam-Val-Wiz, Dwa-Elf-Hum-Orc, Cha-Law, Fem-Mal
Underway: Ran-Gno-Neu-Fem
To go:    Arc-Cav-Hea-Kni-Mon-Pri-Rog-Tou


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