This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Fix other/44566


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]