Hello All,

Andrew Pinski wrote:
On Sun, Oct 12, 2008 at 1:15 PM, Basile STARYNKEVITCH
<[EMAIL PROTECTED]> wrote:
Hello All,

I am sometimes wishing to be able to scan some few local variables in GCC
garbage collector, GGC.

The only time I can think of when you want to do that is when the pass
creates lots of garbage.  The only pass I can think of that might
cause that much garbage is the inliner but even then it would only be
make stuff dead rather than creating new data structures which are
dead.

Can you give a more concrete example of why you want this?

Yes, the MELT branch. There is some incomplete documentation on the wiki, and in the MELT branch itself, file gcc/doc/melt.texi.

The MELT runtime (file gcc/basilys.c) provides a copying garbage collector backed up by GGC. So a minor MELT GC copy live MELT values out of MELT nursery zone into the GGC heap; a full MELT garbage collector triggers in addition ggc_collect.

MELT handle MELT values (like MELT closures, MELT objects, MELT boxed gimples) and unboxed stuff. Stuff means any GCC data which is not boxed as MELT value. For instance, gimple & gimple_seq are stuff.

The point is that a MELT garbage collection can essentially occur at any time within MELT code. More precisely, a MELT GC basilys_garbcoll can occur at any invocation of basilysgc_allocate which allocate MELT values in the MELT nursery; this happens very often in the C code generated by MELT. Most such collections are only minor (so do not call ggc_collect) but some of them are full (they do call ggc_collect after copying out of the nursery). So potentially ggc_collect can be called (via basilysgc_allocate which calls basilys_garbcoll which may call ggc_collect) at many places in MELT generated code. Remember that all MELT code (including the MELT translator itself) is machine-translated to C code.

MELT is currently only used for analysis passes, ie passes which are acessing GCC internal representations (like gimple & tree & edge & cfg etc..) but which do not modify them (like any optimizing pass should do). For such passes the current MELT code (ie the generated code and the gcc/basilys.c file) is enough and safe.

Now suppose you want to prototype in MELT a pass which does some cute & expensive optimisation. (This does not happen yet; MELT is currently only used for analysis purposes, and I am still working on such analysis code - see files gcc/melt/ana-*.bysl). So this pass wants to build a new gimple_seq using e.g. gimple_seq_alloc_with_stmt. Interfacing this to MELT is extremely easy, just code
  (defprimitive new_gimpleseq_with_stmt (:gimple stmt) :gimple_seq
    "gimple_seq_alloc_with_stmt(" stmt ")")
Et voilĂ , you can later code in your MELT code
  (new_gimpleseq_with_stmt s)
with the s variable containing a gimple stuff (of course it can be a more complex MELT expression giving a gimple).

Imagine that just after such an expression a MELT full garbage collection occur. This can happen when you code in MELT an expression which boxes the newly make gimple_seq, like
  (make_gimpleseq (new_gimpleseq_with_stmt s))
This just asks to box the newly made gimple_seq stuff into a MELT value. You'll need that to put the gimple_seq inside a MELT closure or a MELT object (since these contains only MELT values, not unboxed stuff!).

In the rare case a MELT full garbage collection occurs at the make_gimpleseq step, chaos will happen. Because the gimple_seq_alloc_with_stmt has been called and returned the new gimple_seq NGS, and then ggc_collect has been called, and the NGS is not accessible yet.

There is a TODO comment line 35 in file gcc/basilys.h of the MELT branch

/***** TODO:

       if GGC-collected data, e.g. tree-s, edge-s, ... is computed by
       basilys/MELT routines and is referenced only by the
       basilys/MELT call frames, it is lost on full basilys garbage
       collections, because the GGC collector is invoked (on full
       basilys GC) without being aware of such data.

       For basilys code which only inspects but does not create or
       modify such data this won't happen.

       A possible solution might be to generate code which copy such
       GGC data outside (e.g. into some specific GGC vector) on full
       garbage collections. This code might either be another routine
       pointer in our basilysroutine_st structure, or simply be
       invoked by calling the closure routine with a magic incantation,
       i.e. with the xargdescr_ set to (char*)-1

 *****/

I could quite easily enhance MELT such that :
code is generated which traverse all the non-value stuff of MELT call frames and mark them (in the GGC sense). the MELT garbage collector would call ggc_collect_with_local with appropriate arguments to invoke all the above generated code.

Without any ggc_collect_with_local the enhancement would be more tedious. For each stuff datatype (ie any GCC internal data which is not boxed as a MELT value) like gimple gimple_seq edge etc... I would have a vector (declared as GTY-ed gc) and generate the code which would push it there. MELT values are already handled like that.

Since MELT is not used yet to construct stuff, only to scan stuff, I did not implement anything yet, and left it as a TODO. But I hope to have explained why a ggc_collect_with_local would help me. Remember that MELT is a meta-programming facility, C code is always generated (so adding some additional generator code is easy to me).


One of MELT major point is its runtime subsystem, which contains a copying collector backed up by ggc_collect. This won't change anytime soon!

I hope I did explain with enough details. I am willing to explain more if needed (but please read gcc/doc/melt.texi in the MELT branch before asking).


In addition, I also do think that a ggc_collect_with_local would be useful to plugins.

Regards.
--
Basile STARYNKEVITCH         http://starynkevitch.net/Basile/
email: basile<at>starynkevitch<dot>net mobile: +33 6 8501 2359
8, rue de la Faiencerie, 92340 Bourg La Reine, France
*** opinions {are only mines, sont seulement les miennes} ***

Reply via email to