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: F2003 Finalization -- progress and problems


Tobias Burnus wrote:
After finishing the code, I want to write some little documentation
about how finalization works and is implemented if you want so in the
future everyone has it easier to work on it (now that I still know how
it works...), if you point me where to write this.
GREAT idea! I think gfc-internals.texi is the best place, see:
http://gcc.gnu.org/onlinedocs/gfc-internals/
(An alternative would be the Wiki, but I think gfc-internals.texi is better.)

I also like the TexInfo better, so we've agreed here ;) But this will have to wait until the code is ready for check-in I think, then we can discuss this again.


c) what exactly does that "specification expression in scoping unit"
mean?  But otherwise, this sounds similar to b).

"If a specification expression in a scoping unit references a function, the result is finalized before execution of the first executable statement in the scoping unit."


"7.1.6 Specification expression"
"R729 specification-expr is scalar-int-expr"
"C710 (R729) The scalar-int-expr shall be a restricted expression."
"A *restricted expression* is an expression [...], and where any final subroutine that is invoked is *pure*."

But then nothing needs to be finalized if the result has to be integer... Or did I miss something?


b) results of functions and structure-constructors after they have been
used: I'm not sure how this could be done in resolution-phase (without
"rewriting" the code and introducing temporaries), but maybe in trans
this will be easier. Any ideas and tipps?
I don't quite understand what with "after they have been used" is meant - nor can I find it in the standard. (Currently, I have no opinion whether on should use trans*.c or resolve*.c.)

In the subsection "When finalization occurs":


...

"If an executable construct references a function, the result is finalized after execution of the innermost executable construct containing the reference.

"If an executable construct references a structure constructor, the entity created by the structure constructor is finalized after execution of the innermost executable construct containing the reference."

My problem here is that if we have something like:

x = foobar (funct (x)),

where funct returns a finalizable entity. Then we need to generate code like that:

temp = funct (x)
x = foobar (temp)
finalize (temp)

If I did understand the code correctly. Are such nested constructs flattened in trans like the above or is this passed down like it is to the middle-end and converted there? In the latter case, we would need to split it and introduce temporaries manually during either resolution or trans to handle the finalization (in that case when both are equally possible, I'd prefer resolution as working on the gfortran-trees is probably easier as more information is available). Or do you have better ideas?

I think it should not be too hard to do those splitting of expressions, although it surely makes the code uglier, but I don't see any other way to handle the finalization-requirements of the standard.

e) intrinsic assignment: for ordinary assignments this is handled
What do you mean by ordinary assignments? If you mean a simple

Right, I mean assignment not in WHERE/FORALL; I believe somewhere in the code this is called "resolve_ordinary_assignment" ;)


 type(t) :: x, y
 y = x

then this is an intrinsic assignment unless you have "assignment(=)" anywhere. Using

 interface assignment(=)
     subroutine assign_t(x,y)

the finalization happens automatically as the LHS argument matches a INTENT(OUT) in assign_t.

Ah, yes! But I have to make sure the LHS is not finalized twice in this case; the old patch *should* already handle this, but at the moment there's no test for this. That will be changed of course.


WHERE (arr == 2)
     arr = 5
END WHERE

Should this finalize the whole masked arr at once or each element before
it is overwritten?  Can there be a similar unclarity for FORALL?
I really dislike WHERE as it is (at least to me) a bit intransparent what happens there. Maybe something to ask at lang.comp.fortran.

I myself don't have much experience with WHERE, only looked at it briefly once. From a programmer's point of view, it sounds nice to me (or, better, like a neat feature that let's you express some thing in an elegant way; but it might be something that's never really needed anyway, I don't know). But I believe this will be some mess implementing...


I read this as follows, but now guarantees that I interpret the standard correctly.

{
 tmp = function(array)
 finalize(array(mask))
 array(mask) = tmp(mask)
}

That makes sense, so finalizing the masked array.


FORALL: I have not yet fully understand how this should be handled, but note:

"C738 (R756) Any procedure referenced in a forall-body-construct, including one referenced by a defined operation, assignment, or *finalization*, shall be a *pure* procedure."

And for PURE procedures:

"C1273 Any procedure referenced *in a pure subprogram*, including one referenced via a defined operation, assignment, or *finalization*, shall be *pure*."

Do you mean I have to check on finalization if the only calls are pure procedures and output an error otherwise? Hm... It gets even nicer...


I was more thinking about the expression "x + foobar (x)" in itself rather than the I/O; that's because foobar (x) changes the value of x and I wanted to know whether it was defined or not if the first x had the earlier or later value.

In other words: The program is invalid and the compiler can do anything. (The saying goes this includes starting WW3.)

Thanks, that's what I was looking for.


+    TYPE(yes_t), ALLOCATABLE :: alloc_vector(:)
+    ! alloc_vector is deallocated automatically here
+    ! XXX: Or not?

BTW, I was a bit surprised when I first read about this nice feature of automatic deallocation (and automatic allocation the like)--Fortran isn't C++ :D
That is one of the nice features of Fortran: With allocatable, one cannot have loose memory. If one tries to allocate an already allocated variable, one gets an error; and when the variable goes out of scope, it is automatically deallocated.

This is implemented now, I did this other than everything else so far in trans as I believe this automatic deallocation is added there.


How about ALLOCATABLE components? I saw in the code there that all those are recursively deallocated during deallocation of an entity. So this means we have to finalize those, too, before they get deallocated, right? But maybe this isn't much effort now I've already some experience (and code) for doing the finalization in trans.

The problem with this is just that I need the original gfc_expr for this, as I have to have access to the derived-type structure and similar for access to the finalizer-procedures and the like. And this lets me reuse the existing finalization-code :D

Cheers,
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]