Brendon Costa wrote:
Hi all,
Firstly, do others think it would be helpful to summarise any of this
information on a wiki page, or will these emails be fine?
Yes, updating the wiki is always nice. Don't forget to put reference to
the mails on gcc@ using their archive URL, please!
In this email I will give my opinion on the questions asked by Deigo and
ask a few additional questions that may be relevant.
------------------------------
What features do we want to support?
* Hooks
I like the sound of what Taras described in terms of the actual format
of defining the hooks throughout the GCC code. The hooks i currently use
for my project are (in GCC 4.0.4):
But what about the trunk, which uses tuples?
Are the below hooks the name of dlsym-ed symbols inside the plugins, or
the name of some (new or existing) functions?
- c_common_init(), c_common_finish(), finalize(), gimplify_function_tree()
How do we interact with the pass manager? Some plugins definitely want
to add new passes... How does that happen concretely?
* Automatically loaded plugins as well as explicit user requested plugins
I would like to propose that we allow automatic loading of certain
plugins in addition to the explicit request for loading of plugins using
the -fplugin=<name> command line option.
The idea is that their are two "types" of plugin that are differentiated
only by the location in which they are installed and how they are loaded
by the GCC application(s). The first type of plugin as has been
discussed is loaded on explicit user request with -fplugin=xyz, the
second is a plugin that is always loaded automatically on execution of
the GCC application(s).
Agreed, but perhaps this autoload feature is not the first priority.
Making plugin working inside the trunk seems more important to me than
the autoload thing. At last, autoload plugins might slow down quick
compilation of very small files (but do we care?).
The main reason i see for such a feature is that it allows automatically
loaded plugins to become "transparent".
Agreed. Besides, I believe that we cannot reliably predict how plugins
will be used in the long run. And in contrast to the email of Joseph S.
Myers <[EMAIL PROTECTED]> I also
think that it may latter happen that some optimisations would in the
future exist only as plugins.
A related issue (which does not seems a priority to me) is do we want to
make easy the process of moving a plugin inside the core GCC code,
precisely to avoid that (ie having significant optimisations as plugins).
------------------------------
What should we export?
* I think that exporting as much as we can from GCC is good (say
everything but the main() function), not just a limited sub-set that
plugins can access. This gives the most flexibility for plugins (even if
we don't foresee people using all this at any point for now).
Agreed. And I should also mention that I personally am not interested by
Win32 (so I don't care of declspec(dllexport)...).
Possible reasons against exporting everything:
* If we want to define a stable API for plugins then we would not export
everything. To be honest i think doing something like this would be too
much work for the benefit.
We really cannot care (at least now) to define a stable API. If we did
care about that, plugins would never happen. It has been agreed at the
plugin BOFS at last GCC Summit (june 2008 Ottawa) that defining a stable
API for GCC internals is not realistic (and perhaps even not preferable).
------------------------------
What should be the user interface to incorporate plugin code?
It has been proposed that we use:
-fplugin=<name> -fplugin-arg=<arg>
I propose that we use slightly different format:
g++ -fplugin=<name> -f<name>-<arg>[=value]
Seems nice. But this convention might hurt the current arguments.
Currently, this convention implicitly prohibits (but that is ok for me)
a plugin named loop because -floop-block already means something.
There are some problems though with my proposal. In particular:
* A plugins name can not be the same as an existing -fxyz option.
Yes, this is what I mentioned above.
=================
And there is one significant point we did not discuss yet. Compiling a
plugin should if possible be doable outside of GCC source code; this
means at least that the gcc/Makefile.in should have stuff to copy all
the relevant *.h files usable by plugins outside. The MELT branch does
that already using code like (I'm pasting some lines of my
gcc/Makefile.in). I do know that it is ugly, uses some -MMD -MF flags
which are gcc specific, probably a depcomp script should be better.
## this is the local build directory (which should be copied during
## installation into the installation directory above) for include-d *.h
melt_build_include_dir= melt-private-build-include
Maybe this is not the business of GCC, and only an issue for GCC
packagers. In general, we should have a convention for the file path of
installed plugins : do we want them only in system places like /usr/lib
or also a per-user directory like $HOME/.gcc-plugin-dir/4.5.0/ ; we also
need a convention for the location of all the related *.h files needed
to compile a plugin outside GCC source tree. (or is this a packaging
issue only, ie have not only a gcc-4.5 package in debian, but also
gcc-4.5-plugins-dev package? - but that should mean additional install*
targers in our Makefile.in).
## the C flags (without any gcc -I...stuff) to be included in
## compilation of MELT generated C code thru the melt-cc-script do not
## put $(INTERNAL_CFLAGS) $(COVERAGE_FLAGS) $(WARN_CFLAGS) $(T_CFLAGS)
## there!
MELT_CFLAGS= $(X_CFLAGS) $(CFLAGS) $(XCFLAGS) $(INTERNAL_CFLAGS) @DEFS@
# we want to generate all the direct (non system) dependencies of run-basilys.h
# the following should work if $(CC) is some recent version of GCC (probably >=
4.x)
# we first generate the make-dependencies using -MMD
# this should write into run-basilys.d some stuff like
## run-basilys-deps: srcdir.../gcc/run-basilys.h config.h auto-host.h ....
# with the srcdir... replaced by the source directory
# however, there are also config/ files in the dependency list
# config/ files should be handled specially since they are the only #include-d
files
# which are not flat, ie in a subdirectory, like
srcdir.../gcc/config/i386/x86-64.h
# there is also a dependency on tm.h (in objdir) which contains stuff like #include
"config/i386/x86-64.h"
run-basilys.d: run-basilys.h \
$(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) $(TM_H) $(TREE_H) $(GGC_H) \
tree-pass.h basilys.h gt-basilys.h
## perhaps this should really use depcomp, because this works only if
## CC is some gcc 4.x since it use the precompiled headers feature
$(CC) -MT run-basilys-deps -MMD -MF $@ $(ALL_CFLAGS) $(ALL_CPPFLAGS) $<
-o run-basilys.h.gch
.PHONY: run-basilys-deps
## the include below defines the dependencies of run-basilys-deps
## included file run-basilys.d is generated above
-include run-basilys.d
## copy all the file in the dependency of run-basilys-deps into
$(melt_build_include_dir)
## but handle the $(srcdir)/config/ files specially by copying them within a
config/ directory
## and the */*-tree.def files such as ada/ada-tree.def cp/cp-tree.def ...
likewise
run-basilys-deps:
ifdef BASILYSMELT_OBJ
$(mkinstalldirs) $(melt_build_include_dir); \
for f in $^ ; do \
rf=`realpath $$f` ; \
cf=`echo $$rf | sed
"s:$(srcdir)/config/:$(melt_build_include_dir)/config/:"`; \
tf=`echo $$rf | sed "s:$(srcdir)/:$(melt_build_include_dir)/:"`; \
if [ "x$$rf" != "x$$cf" ] ; then \
$(mkinstalldirs) `dirname $$cf` ; \
cp -p $$rf $$cf ; \
elif [ "x$$rf" != "x$$tf" ] ; then \
$(mkinstalldirs) `dirname $$tf` ; \
cp -p $$rf $$tf ; \
else \
cp -p $$rf $(melt_build_include_dir)/ ; \
fi; \
done
endif
======================
------------------------------
At what point in the compilation stage should it kick in?
I think plugins should be loaded as soon as possible.
Yes. The minor point is should we avoid loading plugins when they are
not used? My view is that this is not a priority. But I am probably not
caring enough about the time of small compilations (i.e. the time of gcc
-O0 helloworld.c)
------------------------------
Some extra questions.
------------------------------
What platforms do we want to support? I can think of the following
categories:
* Old platforms (No dlopen support)
Do we use the libltdl dlpre-opening to at least support "plugins" that
may be officially distributed with GCC?
We really should not care about plugins on plateforms without dlopen.
What is more important is that GCC should be configurable to have
plugins disabled and still (at least) be able to compile itself (or
perhaps a reduced version of itself).
* Windows (cygwin/mingw)
As i understand the issue (I am not very familiar with this) you can't
have unresolved references in a plugin back to the GCC executable. I.e.
Building GCC with -rdynamic will not work on this platform. [....]
Or are we going for the quick solution of using -rdynamic and not
supporting this platform (Not my preferred option)?
I would prefer that (ie using -rdynamic). Perhaps a convention (i.e.
adding a EXPORT_PLUGIN macro to mark exported symbols) should be defined.
* "Newer" ELF platforms
These should be fine regardless of the method we use i think.
------------------------------
How do we search for plugins and make sure we don't load incompatible ones?
[...]
$libdir/gcc/i386-unknown-netbsdelf3.0/4.3.2/plugins/
Then comes the issue of thinking about how does an external project
locate that directory? Do we add an option to the command line of GCC to
obtain this directory name?
We definitely need that option.
------------------------------
How/where do we install headers and the library for external plugin
projects to use?
Yes, this is an important question. I suggested some ideas (and even bad
code) above.
Thanks for the interesting message.
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} ***