This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA: Fix other/44566
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: Joern Rennecke <amylaar at spamcop dot net>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 26 Jun 2010 17:00:50 +0000 (UTC)
- Subject: Re: RFA: Fix other/44566
- References: <20100626061802.45a3nzzz4088o840-nzlynne@webmail.spamcop.net>
As I noted, some time ago I did an analysis of what would actually need to
change for a proper multi-target toolchain, and of the issues that would
arise. Here are comments based on that analysis.
I should point out that the model I was thinking of in that analysis (of
the features supported by the multi-target toolchain) was somewhat
different from yours; the two overlap in what changes are needed, but each
model involves significant changes not needed by the other model. Thus,
for several issues I identify, in your model they may well be less of an
issue because they relate to things you explicitly do not expect to work.
Nevertheless, I think they are relevant to understanding what the
limitations of any proposed approach are.
The model I has was that all the targets supported by the compiler are
essentially equal. It would be possible to run the compiler - or other
components such as the assembler - with a --target= option to select a
particular target, and the results would be identical to those of a
single-target compiler for that target. Some method would be added for
configure options to be specified to apply to a single target only. (Your
patch appears to discard all configure options when running sub-configures
for secondary targets, which doesn't seem right either.) Thus each target
could have its own search paths for libraries and headers, for example,
and its own set of multilibs. Runtime libraries would be configured (for
each multilib, for each target) with the appropriate --host for that
target, and when the testsuite is run DejaGnu would be told it was run for
one of the targets involved, so hardcoded target triplet names in those
places would not need to change. Can the testsuite be run at all for
secondary targets with your implementation?
My model did not include the possibility of a single compilation using
more than one target in a single source file.
We estimated in CodeSourcery that this would take on the order of two
person-years to implement.
I did not think of your approach of using namespaces and compiling some
source files many times, which avoids some of the changes I thought
necessary but still requires a reliable way to identify target macros and
where they are used so you can tell what files need to be built multiple
times. I was supposing each file to be built once, and there to be no
tm.h at all included in most files, except maybe for a few files built
once per target that use headers such as tm.h solely to define
initializers for a target vector initialized in those files.
(When I refer to target macros, macros in config.in that are defined by
configure, and might be defined differently for different targets, are
subject to exactly the same issues of needing to depend on the target and
needing to identify which files use them.)
Changes I expected to be needed
-------------------------------
* Completing the move of every last target macro into the target
structure. The intermediate conversion step of functions in targhooks.c
that call target macros is not enough.
* Likewise in some way for all the target macros specific to a given CPU
target (e.g. those local to config/rs6000).
* All target macros used in the driver gcc.c (etc.) must move into a
separate target structure (that doesn't presently exist) in the driver
program. (This covers many spec strings, for example.) Other programs
such as collect2 also need their own target structures.
* libgcc must stop using target macros from tm.h; it can use macros
predefined by the compiler instead, but every target macro use in libgcc
needs tracking down and removing. As I was envisaging the gcc/ directory
being configured only once, properly completing the toplevel libgcc
transition is indicated.
* Likewise for other runtime libraries - at least libobjc.
* Generated data and functions used in the driver, such as multilib data
and command-line option information, must move into the target structure.
* Generated data and functions used in the compiler proper must move into
the target structure. This includes the gen_* functions for individual
instructions, for which there are very many calls hardcoded throughout the
compiler: some sort of renaming is needed to allow multiple targets which
get different generated function implementations to be used.
* There must be configure syntax to make all the configure options depend
on the particular target for which the compiler is run, instead of being
global.
* Similar issues arise elsewhere. The assembler has no beginnings of a
target structure like that in GCC. The linker, BFD and GDB are much
better in this regard but BFD still has quite a few #ifdef cases (I
haven't checked whether they relate to code built multiple times or
whether they are actually harmful to proper all-target support).
Differences with your approach
------------------------------
With your approach, you define some specific areas where secondary targets
will not behave like primary targets. Thus header search paths do not
need defining for secondary targets, since headers and predefined macros
will always be based on the primary target, and secondary targets are not
expected to get their own type sizes. You would also appear to have the
driver's behavior based on the primary target only.
I would however expect functions built for secondary targets still to need
libgcc for some purposes, so you would need to work out how it is to be
built, where it is to be installed and how it is to be found at runtime
(for each secondary target multilib) ... with additional complications
relating to functions for different targets being combined in a single
object.
I noted the issues of target macros used within a config/$arch directory
to control compilation of code within that directory. Do you treat every
source file in such a directory as target-specific, so they are built
multiple times if there are multiple targets for that architecture? (For
example, Power targets that do not include e500.h have e500 support
disabled at compile time. If configured with target powerpc-linux and
extra target powerpc-eabispe, would two copies of the config/rs6000 files
be built, and two copies of all the generated insn-* files, the copies for
powerpc-linux having e500 support disabled and those for powerpc-eabispe
having it present?)
By building files multiple times you avoid dealing with *some* target
macros - but my claim is that it needs to be a well-defined set of files
that are built multiple times, and all macros used outside that set of
files either need to be defined not to matter for clear reasons, or need
to be converted to hooks.
I noted issues with the intermediate conversion of macros to hooks via
default definitions in targhooks.c that call a macro for unconverted
targets. Your patch places a lot of conditionals / target-specific
markers in targhooks.c. It might be significantly simplified if you
completed the transition for all the partly-transitioned macros....
I mentioned command-line options. This is an area where I would think
your approach makes things much *more* complicated since you need to deal
with option settings on a per-target basis (different targets change the
settings of target-independent optimization flags in different ways, for
example, even if you don't actually allow command-line options to be
marked as applying to an individual target or allow "target" attributes to
be used in conjunction with your per-architecture functions.
As you will have seen I've been working on option handling machinery
lately with a view to changes to how multilib selection works. Your patch
seems to insert a lot of conditionals in option-handling code (and
inserting a lot of conditionals in *any* file generally seems a bad idea).
Part of the model I envisage implementing is that option-handling hooks
will set not global variables but elements of an options structure and
that the compiler can contain multiple such structures. I'd think that
multi-target option handling should be a lot easier after those changes
are in place, since you would have separate structures (including both
target-independent and target-dependent options) for each target and hooks
could set target-independent options in a target-specific copy of the
structure. (Properly, you'd then change all references to global options
to explicitly look at current-function options instead; the quick hack
would be to swap options structures when changing target architecture.)
--
Joseph S. Myers
joseph@codesourcery.com