This is the mail archive of the
mailing list for the GCC project.
Re: RFA: remove tm.h include from function.h
On Thu, 25 Nov 2010, Joern Rennecke wrote:
> > There's a case for having multiple tm.h variants for different uses. For
> > example, completing the toplevel libgcc transition will involve some
> > headers in libgcc/config for those cases where target macros really are
> > appropriate rather than built-in macros and functions and other similar
> > approaches.
> Would that then be macros that would be available to user programs via
> an installed header file?
> Or are you talking about ways to identify the build time or other
> circumstances of building the package?
> Otherwise, I'm at a loss why the libgcc should be able to do things that
> user code couldn't do.
I am talking about making configuration in $target/$multilib/libgcc/
entirely independent of that in gcc/ - thus, having libgcc not use any
configuration information derived from building or configuring the gcc/
directory. This has several advantages, including much cleaner ways for
libgcc configuration variables to depend on the multilib (so different
multilibs can built different source files into libgcc), and the
possibility of building libgcc separately from building the compiler
It ought to be possible to change the set of multilibs after the compiler
is built, but building libgcc with an installed compiler isn't readily
possible at present.
It also ought to be possible, when bootstrapping a cross compiler and
associated libc, to build and install the compiler just once with all
relevant features enabled, then iterate on the alternate sequence of GCC
library and libc builds, rather than needing to do multiple rebuilds of
the whole compiler. (At present, building for a GNU/Linux target, you
need to build a minimal compiler with static libgcc in order to configure
glibc and install its headers and crt*.o and build a dummy libc.so, which
in turn are needed to build the second compiler with shared libgcc, which
in turn allows you actually to do a full glibc build, which in turn is
needed to build non-C runtime libraries from GCC.)
Certain macros used in libgcc, such as DECLARE_LIBRARY_RENAMES in
particular, seem to be clear cases for use of target macros - but the
headers containing those macros should be under the libgcc directory, and
selected by configure code in that directory. See
<http://gcc.gnu.org/wiki/Top-Level_Libgcc_Migration> for some lists
classifying some of the target macros used in libgcc.
Furthermore, I would like to see source files in GCC including headers
defining macros and declaring types and functions only where those macros,
types and functions are (a) appropriate to use in the relevant source
files and (b) actually available in all programs into which the resulting
objects are linked.
Regarding (b), code built for the target should not include anything
involving the "tree" type at all. Nor should code built for the driver
(or collect2, gcov etc.) because the "tree" interfaces aren't available
there. You should never get a link error from accidental use of an
interface not available in the GCC program you are linking without first
getting an error or warning about an undeclared function. As I see it,
there should be some common infrastructure, usable everywhere and linked
into all GCC programs (and using a cut-down coretypes.h not mentioning any
irrelevant types, and not using tm.h or target hooks of any kind at all);
further code shared by the driver and the compilers proper but not other
programs (this includes option handling); and the code for the core
compilers; these could use subdirectories to make the separation clearer
Regarding (a), as well as containing definitions for different programs
tm.h contains definitions appropriate for different places. There are
target-specific macros such as TARGET_64BIT, which should only ever be
used within code in config/ (including the .md files, and insn-*.c
generated from them). And there are the macros that are actually intended
to be used directly in code outside config/ - BITS_PER_UNIT is one of
those. Because definitions of the latter macros may use the former
macros, splitting these into separate headers is tricky, but I think the
aim eventually should be to eliminate the latter case completely.
I discussed further advantages of splitting up tm.h (by where the
different macros are used) in
> > then create a separate set of
> > configuration headers for them in the source tree.
> I was kinda hoping we could stop at BITS_PER_UNIT...
If you want to stop at BITS_PER_UNIT, do not go extracting definitions
with grep. Have config.gcc define tm_bits_per_unit_file like it defines
tm_file - all existing targets might use "8bit-unit.h" as the definition.
Create tm-bits-per-unit.h based on the tm_bits_per_unit_file definition,
and have tm.h include tm-bits-per-unit.h. (Plus all the usual dependency
updates.) That would certainly be better than your patch in terms of
removing dependencies - direct or indirect - of source files on the full
set of tm.h headers.
> > Such changes should *definitely* not be mixed in with any other patch like
> > you have done here.
> So what do you propose to do instead? Including tm.h in more source files?
Don't mix together changes made for different reasons. Send them
individually. Ideally, each change you send should be impossible to
subdivide into parts that we might want to consider separately,
because each of its parts gets its motivation from the other parts.
This patch could be divided into *at least* three parts.
(i) The parts adding explicit tm.h includes, or comments on such includes,
to files using target macros. Those should be reasonably uncontroversial.
(ii) Creation of tm-bits-per-unit.h, and replacing selected tm.h includes
with includes of the new header.
(iii) The actual function.h changes, though as noted I think they are
following the wrong approach.
> > but at least for CUMULATIVE_ARGS it would be better to
> > remove all variables and fields of that type from target-independent code,
> I consider calls.c and function.c target-dependent, but I'm not sure if
> you do too. Could you clarify?
I consider everything in gcc/, outside of gcc/config/ to be
target-independent, except maybe for a few misplaced files such as
mips-tdump.c and mips-tfile.c.
> > instead using a target-independent type and having targets responsible in
> > some way for allocating and deallocating values of that type.
> AFAICT the meaning of this statement becomes either approval or rejection of
> the basic premise of my patch depending on how the above question is answered.
I don't think target-independent files should use types whose definitions
depend on the target. The more substantial the target dependence, the
more desirable that target-independent files should not use the type.
When a target-independent file is being compiled, the target-specific
definition of CUMULATIVE_ARGS should not be visible to the host compiler
at all. Where a target-independent file needs to use a datastructure
involving such target-dependent data, it should do so through a
target-independent type. The code under config/ should then do the
necessary base-to-derived-class dynamic casts. The fact that there exists
a type called CUMULATIVE_ARGS in each back end would then become a
historical coincidence rather than an actual requirement that back ends
make any use of such a type name in future.
I consider your patch
<http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01994.html> to be a
reasonable start towards implementing such an approach for CUMULATIVE_ARGS
- but to complete it, get_cumulative_args and pack_cumulative_args should
move into each target's code, all instances of CUMULATIVE_ARGS outside
config/ should go away and additional interfaces should be added to
initialize a cumulative_args_t for a target (which would involve
allocating the target-specific storage) and to finish using it
(deallocating storage, though this probably isn't important).
HARD_REG_SET could be trickier (more likely to involve performance cost if
you abstract it away everywhere) but you could at least replace it with a
void * pointer in function.h and use inline functions defined elsewhere to
convert to/from the actual HARD_REG_SET type.
Joseph S. Myers