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} ***