Quoting Paolo Bonzini <bonz...@gnu.org>:

I think a multi-target executable would be just too ugly in C due to
issues such as this.  I don't think it's worthwhile to sacrifice type
safety now, so a struct cumulative_args is preferrable.

I don't see how going to a struct cumulative_args gets us closer to
a viable solution for a multi-target executable, even if you threw in C++. Having the target describe a type, and shoe-horning this through a target
hook interface that is decribed in supposedly target-independent terms
will require a cast at some point - either of the hook argument that
describes the cumulative args, the hook pointer (not valid C / C++), or
a pointer to the target vector, or a pointer to some factored-out part of
the target vector.  Converting an empty base class to a derived class
is not really safer than converting a void * to a struct pointer.
And switching to a dynamically typed language is not really on the
agenda...

Fully hookizing the CUMULATIVE_ARGS taking macro has really landed us with
this typing mess.  If we had only used targhooks.c wrappers around the
original macros, we could still enjoy type safety for the
targhooks.c / target interface, a sane include hierarchy, and easy extension
to a multi-target compiler.
I'm afraid the only sane way to have these hooks is changing the CUMULATIVE_ARGS pointers into void pointers. As I said before, we can
make this more readable by using a typedef cumulative_args_t;
but there has to be a cast in every CUMULATIVE_ARGS taking target hook
implementation, or in a helper function which the hook uses (unless the
argument is unused).

All in all it's a 136 KB patch; I'm currently writing the ChangeLog
and running 38 builds.


I've tried auto-generating a union before, and for some targets there are
macros that cause conflicts.  To get a cumulative_args union reliably would
require separate header files for each target's definition.  And you'd still
have to select the target's field inside of each hook implementation - that
is a direct consequence of an interface that connects not the target-specific
middle-end to one target, but all parts of the compiler to potentially
every target.

The alternative would be to undo the the hookization of the CUMULATIVE_ARGS
taking hooks.  Tying the middle-end code that deals with calls again a bit
closer to the target, but allowing all the other parts of the compiler to
be blissfully ignorant of these interfaces.

In C++, you could make the middle-end be a template that takes the target
as a parameter, including a CUMULATIVE_ARGS type.  But that's not much more
than syntactic sugar for having the targets setting different macros and
compiling the middle-end accordingly.

Reply via email to