public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* RFC: semi-automatic hookization
@ 2010-11-15 11:17 Joern Rennecke
  2010-11-15 16:33 ` Joseph S. Myers
  0 siblings, 1 reply; 24+ messages in thread
From: Joern Rennecke @ 2010-11-15 11:17 UTC (permalink / raw)
  To: gcc

With 638 macros documented by @defmac, and 475 files that include tm.h ,
our current approach to hookization is too slow to get the tree optimizers
and front ends independent of target macros in any useful timeframe.

Therefore, I propose the following approach:
The target macros currently required by tree optimizers and frontends
get wrapper hooks, and these wrapper hooks get wrapper macros, to look
like the original target macros, defined in the auto-generated
header-file target-wrap.h .  cc1/cc1plus etc. source
files that currently include "tm.h", but have no business to do so, will
be changed to include target-wrap.h instead; if they include "tm_p.h",
this include will also be removed.

The @defmac definitions from tm.texi.in give a tentative list of macros,
although that is probably incomplete, while some macros are already wrapped
or not needed outside of rtl-centric code.
So I'll convert or generate (in the undocumented case) hook wrapper
definitions for the functional macros definitions that are evidently needed
to perform a bootstrap and various cross-builds.  In particular, I'll
have to fill in argument and return types for each required hook.
I use @wrapper for a syntax similar to @hook, except that no default
definition is specified; instead, it is auto-generated, with a new
auto-generated file target-wrappers.c to implement the hook wrappers.

I'll create all the wrapper hooks initially as sub-members of a new
targetm.wrapper member; If people would like them somewhere else, we can
move them around later, but discussing individual placement of some
sixhundred hooks beforehand would just slow down things too much.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-15 11:17 RFC: semi-automatic hookization Joern Rennecke
@ 2010-11-15 16:33 ` Joseph S. Myers
  2010-11-15 17:45   ` Joern Rennecke
  2010-11-15 22:08   ` RFC: semi-automatic hookization Paolo Bonzini
  0 siblings, 2 replies; 24+ messages in thread
From: Joseph S. Myers @ 2010-11-15 16:33 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gcc

On Mon, 15 Nov 2010, Joern Rennecke wrote:

> With 638 macros documented by @defmac, and 475 files that include tm.h ,
> our current approach to hookization is too slow to get the tree optimizers
> and front ends independent of target macros in any useful timeframe.

I think it's perfectly feasible; I think the two-person year estimate I 
mentioned in <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02675.html> for 
a project that would include a lot more than just eliminating target 
macros is realistic.

A complete conversion of OPTIMIZATION_OPTIONS - a macro defined by lots of 
targets - took me about five hours' work.  Many macros are defined by far 
fewer targets and would be much quicker to convert.  Similarly, creating a 
wrapper in targhooks.c is much quicker than doing a complete conversion of 
a macro to a hook for all targets at one go.

(Those macros that are referenced in libgcc or other target code, in the 
driver, etc., or in #if etc. conditionals, are of course harder.)

> Therefore, I propose the following approach:
> The target macros currently required by tree optimizers and frontends
> get wrapper hooks, and these wrapper hooks get wrapper macros, to look

By wrapper hooks you mean hooks in targhooks.c like the present 
transitional system?

That seems reasonable, but I really don't see the benefit of the wrapper 
macros; they seem like needless complication.  If the hook is defined to 
have the same semantics as the macro, changing the uses to use the hook 
directly is just search-and-replace (plus reformatting if lines go over 80 
characters).

> I'll create all the wrapper hooks initially as sub-members of a new
> targetm.wrapper member; If people would like them somewhere else, we can
> move them around later, but discussing individual placement of some
> sixhundred hooks beforehand would just slow down things too much.

I do not believe this is sensible.  A key point of macro-to-hook 
conversion is to clean up the compiler's target interface, which means 
thinking individually about the correct hook form of each interface.  A 
pile of automatically generated wrappers is hardly better than a pile of 
macros, and it is often the case that a one-to-one correspondence of 
macros and hooks is not appropriate.  It's much better to work in thematic 
groups.


I have previously considered the question of how you identify all target 
macros to know that a conversion is complete.  My conclusion is:

Define a target macro for this purpose to be a macro defined in a config/ 
header listed in tm_file and used in a source file outside of config/.  
This is not sufficient for a multi-target compiler of the form I was 
considering - there are macros such as HAVE_<insn> that are defined by 
generator programs and tested in front ends, and those such as DELAY_SLOTS 
and INSN_SCHEDULING that similarly are defined by generator programs (but 
at least those two are not tested in front ends).  And there are also 
target macros that only get tested in other files in config/.  But it is 
still a very useful step in cleaning up the target interfaces in the 
compiler.

Then any target macro must have at least one of the following properties:

* The macro is tested with #if/#ifdef/#ifndef/#elif in a source file 
outside of config/ (but including front-end subdirectories).  Care is 
needed in identifying such macros through grep because of 
backslash-newline line continuations and because it's possible some macros 
are only tested in generated files not directly in source files.  Of 
course lots of macros tested in preprocessor conditionals will not be 
target macros, but you need to check the definitions of such macros to 
find any cases such as:

    #define FOO TARGET_MACRO
    #if FOO

* The macro is defined by every target.  Such macros could be found by 
going through all the headers in tm_file for some single convenient target 
that does not have too much defined in the headers listed there.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-15 16:33 ` Joseph S. Myers
@ 2010-11-15 17:45   ` Joern Rennecke
  2010-11-15 18:59     ` Joseph S. Myers
  2010-11-15 22:08   ` RFC: semi-automatic hookization Paolo Bonzini
  1 sibling, 1 reply; 24+ messages in thread
From: Joern Rennecke @ 2010-11-15 17:45 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

Quoting "Joseph S. Myers" <joseph@codesourcery.com>:

> On Mon, 15 Nov 2010, Joern Rennecke wrote:
>
>> With 638 macros documented by @defmac, and 475 files that include tm.h ,
>> our current approach to hookization is too slow to get the tree optimizers
>> and front ends independent of target macros in any useful timeframe.
>
> I think it's perfectly feasible; I think the two-person year estimate I
> mentioned in <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02675.html> for
> a project that would include a lot more than just eliminating target
> macros is realistic.

I was more thinking of getting the frontend and tree optimizers weaned off
target macros within one to four weeks.

> A complete conversion of OPTIMIZATION_OPTIONS - a macro defined by lots of
> targets - took me about five hours' work.  Many macros are defined by far
> fewer targets and would be much quicker to convert.  Similarly, creating a
> wrapper in targhooks.c is much quicker than doing a complete conversion of
> a macro to a hook for all targets at one go.

Still, there are so many of them, and we can't reap the benefits till we
have covered all the ones that are used outside of the rtl centric files.

> (Those macros that are referenced in libgcc or other target code, in the
> driver, etc., or in #if etc. conditionals, are of course harder.)

Indeed.  As I said, I intend to focus for the time being on the parts used
in the compiler proper, i.e. cc1, cc1plus etc.

> By wrapper hooks you mean hooks in targhooks.c like the present
> transitional system?

Yes, except that for most of the hooks, I expect to select only the
argument / return types, and let a new or extended generator program
write the hook code.  Some types would nominally have an enum, but actually
use integers, and be casted in the relevant places.  That, too, is supposed
to be handled by the autogeneration program.

> That seems reasonable, but I really don't see the benefit of the wrapper
> macros; they seem like needless complication.

It lets be focus on the part that needs to be done now to get frontend /
tree-optimizer independence from target macros, i.e. define the set
of autoconverted macros and their types, and handle any exceptional
cases.

> If the hook is defined to
> have the same semantics as the macro, changing the uses to use the hook
> directly is just search-and-replace (plus reformatting if lines go over 80
> characters).

Yes, but search-and-replace and reformatting for so many macros is also a
lot of work (if you think ident can do the job, I'd like to see a patch
  submission to indent to do correct and conservative reformatting of
  GCC sources).  Plus, it generates a lot of repository churn.
And the target hook names will probably not be final, so you'd have to
search-and-replace after each hook name or site (targetm sub-struct)
change.

>> I'll create all the wrapper hooks initially as sub-members of a new
>> targetm.wrapper member; If people would like them somewhere else, we can
>> move them around later, but discussing individual placement of some
>> sixhundred hooks beforehand would just slow down things too much.
>
> I do not believe this is sensible.  A key point of macro-to-hook
> conversion is to clean up the compiler's target interface, which means
> thinking individually about the correct hook form of each interface.

As I said, I'll have to assign argument and return types for each wrapper.
That is already an important part of this work.  And if any lvalue or
label arguments appear, that'll need special handling too.
By keeping the conceptually trivial stuff trivial we can focus on the
stuff that actually needs special attention.

Plus, if you want every hook to be well-named and designed, you can see
all the members of targetm.wrapper as a to-do list of hooks that should be
placed in a semantics-related place, possibly renamed etc.

> A
> pile of automatically generated wrappers is hardly better than a pile of
> macros,

It is a useful first step to a better defined target hook interface, and
it will allow us to get rid of dependencies that currently prevent us from
better modularizing the compiler.

> and it is often the case that a one-to-one correspondence of
> macros and hooks is not appropriate.

I expect I'll find some such cases, which I'll have to deal on a case-by-case
basis.  That's not a reason to elevate the difficulty of each detail to the
difficulty of the hardest detail.

>  It's much better to work in thematic
> groups.

My theme is 'everything that gets in the way of a multi-target compiler'.
I understand that you probably mean that you like the hooks grouped together
by theme, like asm_out etc.  Everyone had years to do that, yet the job is
still not done.
You can still re-organize things after I create the wrapper infrastructure;
in fact, I think it'll be easier, since you can focus on what is really
relevant.  E.g. there is little point is replacing every scheduler and
reload macro, unless you want to rewrite most of that code to get rid of
all the #if directives too.  Simple, concise macros like Pmode or  
FIRST_PSEUDO_REGISTER make sense in code that should be specialized for
each target for performance reasons.  You could do this with C++ templates
and LTO, but it'd just make compiler debugging so much harder.

> I have previously considered the question of how you identify all target
> macros to know that a conversion is complete.  My conclusion is:
>
> Define a target macro for this purpose to be a macro defined in a config/
> header listed in tm_file and used in a source file outside of config/.
> This is not sufficient for a multi-target compiler of the form I was
> considering - there are macros such as HAVE_<insn> that are defined by
> generator programs and tested in front ends,

That is true.  We probably want a bitmap of the named patterns for which
the frontends want to test HAVE_xxx, unless the use can be easily replaced
with an optabs query - the latter might work if the frontend wants to know
if an expander is available, but not if the question is if a particular
code generation is suitable because of particular hardware support.

Some of these tests might be better of having special hooks - but again,
there is no limit to the amount of refinements we can make, and if we require
all possible refinements to be present in v1.0, v1.0 will never be.

> and those such as DELAY_SLOTS
> and INSN_SCHEDULING that similarly are defined by generator programs (but
> at least those two are not tested in front ends).

Indeed, I see no need to change such macros as long as they are only used
by rtl passes.  It ain't broken...

> And there are also
> target macros that only get tested in other files in config/.  But it is
> still a very useful step in cleaning up the target interfaces in the
> compiler.

Depending on what the config files do, I might need to address this too
in order to get a multi-target compiler going.  But I'll be content to
start out with being able to link two specific backends together - fixes
to get more backends into shape can be added later.

> Then any target macro must have at least one of the following properties:
>
> * The macro is tested with #if/#ifdef/#ifndef/#elif in a source file
> outside of config/ (but including front-end subdirectories).  Care is
> needed in identifying such macros through grep because of
> backslash-newline line continuations and because it's possible some macros
> are only tested in generated files not directly in source files.  Of
> course lots of macros tested in preprocessor conditionals will not be
> target macros, but you need to check the definitions of such macros to
> find any cases such as:
>
>     #define FOO TARGET_MACRO
>     #if FOO

I will have to be wary of those, and they'll indeed will need code changes.

> * The macro is defined by every target.  Such macros could be found by
> going through all the headers in tm_file for some single convenient target
> that does not have too much defined in the headers listed there.

This is not a very useful criterion, because it covers so many macros that
are not used outside the rtl passes.  It'd have to be filtered against
what is actually used.  OTOH grep will be left blind-sided by token-pasting,
so trying to build for lots of targets will be an important test, too.
This is why I've been working on PR44756 first.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-15 17:45   ` Joern Rennecke
@ 2010-11-15 18:59     ` Joseph S. Myers
  2010-11-16 10:12       ` Joern Rennecke
  0 siblings, 1 reply; 24+ messages in thread
From: Joseph S. Myers @ 2010-11-15 18:59 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gcc

On Mon, 15 Nov 2010, Joern Rennecke wrote:

> Quoting "Joseph S. Myers" <joseph@codesourcery.com>:
> 
> > On Mon, 15 Nov 2010, Joern Rennecke wrote:
> > 
> > > With 638 macros documented by @defmac, and 475 files that include tm.h ,
> > > our current approach to hookization is too slow to get the tree optimizers
> > > and front ends independent of target macros in any useful timeframe.
> > 
> > I think it's perfectly feasible; I think the two-person year estimate I
> > mentioned in <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02675.html> for
> > a project that would include a lot more than just eliminating target
> > macros is realistic.
> 
> I was more thinking of getting the frontend and tree optimizers weaned off
> target macros within one to four weeks.

I don't see why that shouldn't be done *properly* in four person-weeks.  
I can't imagine a problem doing a targhooks.c-type conversion, without any 
wrapper macros, in that time; in four person-weeks it should be possible 
to convert *every single target macro that doesn't have #if-type 
difficulties* to use a properly named and located hook with a default in 
targhooks.c, not just the limited subset used in front ends and tree 
optimizers.

Do you have a list of the macros in question and the targets for which 
they are defined, that together with figures for time-per-macro and 
time-per-macro-per-target makes you think proper conversions are 
infeasible?

I should point out that it's generally better for changes to be done in 
more (and more reviewable and bisectable) incremental patches rather than 
fewer.  Note how my ongoing options/multilibs patch series is at 76 
logical patches so far with plenty more to come.

> > A complete conversion of OPTIMIZATION_OPTIONS - a macro defined by lots of
> > targets - took me about five hours' work.  Many macros are defined by far
> > fewer targets and would be much quicker to convert.  Similarly, creating a
> > wrapper in targhooks.c is much quicker than doing a complete conversion of
> > a macro to a hook for all targets at one go.
> 
> Still, there are so many of them, and we can't reap the benefits till we
> have covered all the ones that are used outside of the rtl centric files.

Important benefits include cleaner internal interfaces, and every macro 
you convert (or remove - sometimes removing a macro is the right approach 
instead of a direct conversion) improves the internal interfaces.

> > By wrapper hooks you mean hooks in targhooks.c like the present
> > transitional system?
> 
> Yes, except that for most of the hooks, I expect to select only the
> argument / return types, and let a new or extended generator program
> write the hook code.  Some types would nominally have an enum, but actually
> use integers, and be casted in the relevant places.  That, too, is supposed
> to be handled by the autogeneration program.

I'd advise making the generator a tools to help in editing targhooks.c and 
other existing source files (such as tm.texi.in), to make the existing 
form of transition easier, rather than something separate and not 
integrated into the existing transition process.

> Yes, but search-and-replace and reformatting for so many macros is also a

I really don't think it's "so many" - and at least I expect most macros 
used in those parts of the compiler are not used in many different places.

> lot of work (if you think ident can do the job, I'd like to see a patch

I'd imagine at most a few seconds per call site.

> submission to indent to do correct and conservative reformatting of
> GCC sources).  Plus, it generates a lot of repository churn.

Repository churn is inevitable in cleanups - and as I said, lots of 
incremental patches is much better than one big one (minimal incremental 
patches is also GCC policy).

> And the target hook names will probably not be final, so you'd have to
> search-and-replace after each hook name or site (targetm sub-struct)
> change.

You need to work with relevant maintainers.  Post the list of macro names 
- and where they are used - and ask relevant maintainers what they want 
the hooks to look like, so as to get the desired names and positions in 
the structure in advance of making the changes.  (And make the program you 
use for the conversion process support inserting things in the places 
people specify, with the names they specify.)  Posting lists will also 
make it easy for maintainers to do their own conversions if they wish.  
What front ends use what target macros?  What tree optimizers use what 
target macros?

Also make sure to work well with existing ongoing work and pay attention 
to already expressed views about what certain hook conversions should look 
like.  Avoid causing problems with the work to make the preprocessor 
predefine the right macros for Fortran.  Note my classification of target 
configuration information in 
<http://gcc.gnu.org/ml/gcc/2010-10/msg00294.html>.  Note what I said in 
<http://gcc.gnu.org/ml/gcc-patches/2010-10/msg01874.html> about how macros 
such as SIZE_TYPE should be converted to hooks, not a one-to-one 
conversion.  Similarly, *_TYPE_SIZE should not be converted one-to-one 
either; I'd suggest having a hook that takes an enum integer_type_kind and 
returns the size, rather than a separate hook for each type - and 
WCHAR_TYPE_SIZE is a target macro that should go away completely without 
being replaced by a hook (it's derivative of information in WCHAR_TYPE, 
and is only now used by Ada).

> That is true.  We probably want a bitmap of the named patterns for which
> the frontends want to test HAVE_xxx, unless the use can be easily replaced
> with an optabs query - the latter might work if the frontend wants to know

We recently noted that optabs don't work for defining preprocessor macros 
because they aren't set up when just preprocessing (as opposed to when cc1 
is actually compiling).

> > * The macro is defined by every target.  Such macros could be found by
> > going through all the headers in tm_file for some single convenient target
> > that does not have too much defined in the headers listed there.
> 
> This is not a very useful criterion, because it covers so many macros that
> are not used outside the rtl passes.  It'd have to be filtered against

My point was how to identify *all* target macros, which I consider a 
useful thing to do.  You can then filter out those you care about.  Or 
produce a list of undocumented target macros (cf. bug 3386 and my old 
message linked from there) so we can move towards tm.texi.in really 
documenting all target macros.

(Personally I think a complete list of target macros that are used in code 
compiled for the target - including various C files in ada/ - would be 
very interesting - those macros are both ones to be careful about in hook 
conversions, if they are also used for the host, and ones that need 
dealing with as part of completing the toplevel libgcc transition.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-15 16:33 ` Joseph S. Myers
  2010-11-15 17:45   ` Joern Rennecke
@ 2010-11-15 22:08   ` Paolo Bonzini
  2010-11-15 22:16     ` Joern Rennecke
  1 sibling, 1 reply; 24+ messages in thread
From: Paolo Bonzini @ 2010-11-15 22:08 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Joern Rennecke, gcc

On 11/15/2010 04:48 PM, Joseph S. Myers wrote:
> * The macro is tested with #if/#ifdef/#ifndef/#elif in a source file
> outside of config/ (but including front-end subdirectories).  Care is
> needed in identifying such macros through grep because of
> backslash-newline line continuations and because it's possible some macros
> are only tested in generated files not directly in source files.  Of
> course lots of macros tested in preprocessor conditionals will not be
> target macros, but you need to check the definitions of such macros to
> find any cases such as:
>
>      #define FOO TARGET_MACRO
>      #if FOO

Augmenting libcpp with a new kind of poisoning that only affect 
preprocessor conditionals would probably make this a lot simpler.

Paolo

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-15 22:08   ` RFC: semi-automatic hookization Paolo Bonzini
@ 2010-11-15 22:16     ` Joern Rennecke
  0 siblings, 0 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-15 22:16 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, gcc

Quoting Paolo Bonzini <bonzini@gnu.org>:

> Augmenting libcpp with a new kind of poisoning that only affect
> preprocessor conditionals would probably make this a lot simpler.

If we don't have a wrapper macro, we can just poison the macro.
I still have to find out how practical that is, but for now let's assume
we can do that.

How about this:
- make a new header tm-poison.h that poisons all target macros, and sets the
   GCC_TM_H include guard.
- include this header in system.h for IN_GCC_FRONTEND
- include this header in tree.h / gimple.h unless GCC_TM_H has been set

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-15 18:59     ` Joseph S. Myers
@ 2010-11-16 10:12       ` Joern Rennecke
  2010-11-16 15:43         ` Ian Lance Taylor
  0 siblings, 1 reply; 24+ messages in thread
From: Joern Rennecke @ 2010-11-16 10:12 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 1303 bytes --]

target.h and function.h include tm.h, and they got data structure dependencies
that are painful to untangle.  function.h requires x_rtl to be split into
a target-type tainted part and one that can be used in tree optimizers  
/ frontends
  (via the inline functions in emit-rtl.c).  To get rid of the tm.h include in
target.h we have to get rid of all the CUMULATIVE_ARG types in hook  
definitions.
Both changes require a lot of changes in config/arm to get arm-eabi  
back to building.  And that's just one of 38 config/<architecture>  
directories.

If the CUMULATIVE_ARG typed hooks had been defined with a wrapper macro, it'd
be just a simple change in one place.  The way things are, it'll require
hundreds of changes throughout the config directory.

Before I go and make all these target changes & test them, is there at  
least agreemwent that this is the right approach, i.e replacing  
CUMULATIVE_ARG *
with void *, and splitting up x_rtl into two variables.

At least with the latter there is one clear alternative: we could have
non-inline accessor functions for the contents of x_rtl, and provide  
the inline versions in emit-rtl.h only for source files that include  
tm.h .That might slow
down the current tree-ssa users, though, e.g tree-ssa-loop-ivopts.c .


[-- Attachment #2: pr46495-patch-arm --]
[-- Type: text/plain, Size: 27635 bytes --]

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 166792)
+++ doc/tm.texi	(working copy)
@@ -4053,7 +4053,7 @@ @defmac FUNCTION_INCOMING_ARG (@var{cum}
 serves both purposes.
 @end defmac
 
-@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} int TARGET_ARG_PARTIAL_BYTES ( void *@var{cum}, enum machine_mode @var{mode}, tree @var{type}, bool @var{named})
 This target hook returns the number of bytes at the beginning of an
 argument that must be put in registers.  The value must be zero for
 arguments that are passed entirely in registers or that are entirely
@@ -4072,7 +4072,7 @@ structure) crosses that boundary, its fi
 @code{FUNCTION_INCOMING_ARG}, for the called function.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE ( void *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
 This target hook should return @code{true} if an argument at the
 position indicated by @var{cum} should be passed by reference.  This
 predicate is queried after target independent reasons for being
@@ -4084,7 +4084,7 @@ passed by reference, such as @code{TREE_
 to that type.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES (CUMULATIVE_ARGS *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
+@deftypefn {Target Hook} bool TARGET_CALLEE_COPIES ( void *@var{cum}, enum machine_mode @var{mode}, const_tree @var{type}, bool @var{named})
 The function argument described by the parameters to this hook is
 known to be passed by reference.  The hook should return true if the
 function argument should be copied by the callee instead of copied
@@ -5018,7 +5018,7 @@ @deftypefn {Target Hook} rtx TARGET_EXPA
 to use as the return of @code{__builtin_saveregs}.
 @end deftypefn
 
-@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (CUMULATIVE_ARGS *@var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time})
+@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS ( void *@var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time})
 This target hook offers an alternative to using
 @code{__builtin_saveregs} and defining the hook
 @code{TARGET_EXPAND_BUILTIN_SAVEREGS}.  Use it to store the anonymous
@@ -5052,7 +5052,7 @@ structure, containing the values that ar
 not generate any instructions in this case.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING (CUMULATIVE_ARGS *@var{ca})
+@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING ( void *@var{ca})
 Define this hook to return @code{true} if the location where a function
 argument is passed depends on whether or not it is a named argument.
 
@@ -5067,7 +5067,7 @@ @deftypefn {Target Hook} bool TARGET_STR
 You need not define this hook if it always returns @code{false}.
 @end deftypefn
 
-@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED (CUMULATIVE_ARGS *@var{ca})
+@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED ( void *@var{ca})
 If you need to conditionally change ABIs so that one works with
 @code{TARGET_SETUP_INCOMING_VARARGS}, but the other works like neither
 @code{TARGET_SETUP_INCOMING_VARARGS} nor @code{TARGET_STRICT_ARGUMENT_NAMING} was
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 166792)
+++ targhooks.c	(working copy)
@@ -167,7 +167,7 @@ default_expand_builtin_saveregs (void)
 }
 
 void
-default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_setup_incoming_varargs (void *ca ATTRIBUTE_UNUSED,
 				enum machine_mode mode ATTRIBUTE_UNUSED,
 				tree type ATTRIBUTE_UNUSED,
 				int *pretend_arg_size ATTRIBUTE_UNUSED,
@@ -183,16 +183,16 @@ default_builtin_setjmp_frame_value (void
   return virtual_stack_vars_rtx;
 }
 
-/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false.  */
+/* Generic hook that takes a void pointer and returns false.  */
 
 bool
-hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+hook_bool_voidptr_false (void *ca ATTRIBUTE_UNUSED)
 {
   return false;
 }
 
 bool
-default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+default_pretend_outgoing_varargs_named (void *ca ATTRIBUTE_UNUSED)
 {
   return (targetm.calls.setup_incoming_varargs
 	  != default_setup_incoming_varargs);
@@ -247,10 +247,10 @@ default_mode_rep_extended (enum machine_
   return UNKNOWN;
 }
 
-/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true.  */
+/* Generic hook that takes a void pointer and returns true.  */
 
 bool
-hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
+hook_bool_voidptr_true (void * a ATTRIBUTE_UNUSED)
 {
   return true;
 }
@@ -299,7 +299,7 @@ default_cxx_get_cookie_size (tree type)
    of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK.  */
 
 bool
-hook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED,
+hook_pass_by_reference_must_pass_in_stack (void *c ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED,
 	bool named_arg ATTRIBUTE_UNUSED)
 {
@@ -310,7 +310,7 @@ hook_pass_by_reference_must_pass_in_stac
    version of the hook is true for all named arguments.  */
 
 bool
-hook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+hook_callee_copies_named (void *ca ATTRIBUTE_UNUSED,
 			  enum machine_mode mode ATTRIBUTE_UNUSED,
 			  const_tree type ATTRIBUTE_UNUSED, bool named)
 {
@@ -540,8 +540,8 @@ default_builtin_reciprocal (unsigned int
 }
 
 bool
-hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false (
-	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+hook_bool_voidptr_mode_tree_bool_false (
+	void *ca ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED,
 	const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
 {
@@ -549,8 +549,8 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool
 }
 
 bool
-hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (
-	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+hook_bool_voidptr_mode_tree_bool_true (
+	void *ca ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED,
 	const_tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
 {
@@ -558,8 +558,8 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool
 }
 
 int
-hook_int_CUMULATIVE_ARGS_mode_tree_bool_0 (
-	CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+hook_int_voidptr_mode_tree_bool_0 (
+	void *ca ATTRIBUTE_UNUSED,
 	enum machine_mode mode ATTRIBUTE_UNUSED,
 	tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED)
 {
@@ -567,13 +567,13 @@ hook_int_CUMULATIVE_ARGS_mode_tree_bool_
 }
 
 void
-default_function_arg_advance (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_function_arg_advance (void *ca ATTRIBUTE_UNUSED,
 			      enum machine_mode mode ATTRIBUTE_UNUSED,
 			      const_tree type ATTRIBUTE_UNUSED,
 			      bool named ATTRIBUTE_UNUSED)
 {
 #ifdef FUNCTION_ARG_ADVANCE
-  CUMULATIVE_ARGS args = *ca;
+  CUMULATIVE_ARGS args = *(CUMULATIVE_ARGS *) ca;
   FUNCTION_ARG_ADVANCE (args, mode, CONST_CAST_TREE (type), named);
   *ca = args;
 #else
@@ -582,7 +582,7 @@ default_function_arg_advance (CUMULATIVE
 }
 
 rtx
-default_function_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_function_arg (void *ca ATTRIBUTE_UNUSED,
 		      enum machine_mode mode ATTRIBUTE_UNUSED,
 		      const_tree type ATTRIBUTE_UNUSED,
 		      bool named ATTRIBUTE_UNUSED)
@@ -595,7 +595,7 @@ default_function_arg (CUMULATIVE_ARGS *c
 }
 
 rtx
-default_function_incoming_arg (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+default_function_incoming_arg (void *ca ATTRIBUTE_UNUSED,
 			       enum machine_mode mode ATTRIBUTE_UNUSED,
 			       const_tree type ATTRIBUTE_UNUSED,
 			       bool named ATTRIBUTE_UNUSED)
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 166792)
+++ targhooks.h	(working copy)
@@ -35,9 +35,9 @@ extern enum machine_mode default_cc_mode
 extern bool default_return_in_memory (const_tree, const_tree);
 
 extern rtx default_expand_builtin_saveregs (void);
-extern void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
+extern void default_setup_incoming_varargs (void *, enum machine_mode, tree, int *, int);
 extern rtx default_builtin_setjmp_frame_value (void);
-extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
+extern bool default_pretend_outgoing_varargs_named (void *);
 
 extern enum machine_mode default_eh_return_filter_mode (void);
 extern enum machine_mode default_libgcc_cmp_return_mode (void);
@@ -58,9 +58,9 @@ extern tree default_cxx_guard_type (void
 extern tree default_cxx_get_cookie_size (tree);
 
 extern bool hook_pass_by_reference_must_pass_in_stack
-  (CUMULATIVE_ARGS *, enum machine_mode mode, const_tree, bool);
+  (void *, enum machine_mode mode, const_tree, bool);
 extern bool hook_callee_copies_named
-  (CUMULATIVE_ARGS *ca, enum machine_mode, const_tree, bool);
+  (void *ca, enum machine_mode, const_tree, bool);
 
 extern void default_print_operand (FILE *, rtx, int);
 extern void default_print_operand_address (FILE *, rtx);
@@ -91,26 +91,27 @@ default_builtin_support_vector_misalignm
 extern enum machine_mode default_preferred_simd_mode (enum machine_mode mode);
 extern unsigned int default_autovectorize_vector_sizes (void);
 
-/* These are here, and not in hooks.[ch], because not all users of
-   hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS.  */
-
-extern bool hook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *);
-extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
-
-extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
-extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
-extern int hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
-  (CUMULATIVE_ARGS *, enum machine_mode, tree, bool);
+/* These came here, and not into hooks.[ch], because not all users of
+   hooks.h included tm.h, and thus we didn't have CUMULATIVE_ARGS.
+   Well, no we don't have it either way.  */
+
+extern bool hook_bool_voidptr_false (void *);
+extern bool hook_bool_voidptr_true (void *);
+
+extern bool hook_bool_voidptr_mode_tree_bool_false
+  (void *, enum machine_mode, const_tree, bool);
+extern bool hook_bool_voidptr_mode_tree_bool_true
+  (void *, enum machine_mode, const_tree, bool);
+extern int hook_int_voidptr_mode_tree_bool_0
+  (void *, enum machine_mode, tree, bool);
 extern const char *hook_invalid_arg_for_unprototyped_fn
   (const_tree, const_tree, const_tree);
 extern void default_function_arg_advance
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (void *, enum machine_mode, const_tree, bool);
 extern rtx default_function_arg
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (void *, enum machine_mode, const_tree, bool);
 extern rtx default_function_incoming_arg
-  (CUMULATIVE_ARGS *, enum machine_mode, const_tree, bool);
+  (void *, enum machine_mode, const_tree, bool);
 extern bool hook_bool_const_rtx_commutative_p (const_rtx, int);
 extern rtx default_function_value (const_tree, const_tree, bool);
 extern rtx default_libcall_value (enum machine_mode, const_rtx);
Index: c-family/c-opts.c
===================================================================
--- c-family/c-opts.c	(revision 166792)
+++ c-family/c-opts.c	(working copy)
@@ -22,6 +22,7 @@ Software Foundation; either version 3, o
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "c-common.h"
 #include "c-pragma.h"
Index: java/decl.c
===================================================================
--- java/decl.c	(revision 166792)
+++ java/decl.c	(working copy)
@@ -28,6 +28,7 @@ the Free Software Foundation; either ver
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "diagnostic-core.h"
 #include "toplev.h"
Index: java/jcf-parse.c
===================================================================
--- java/jcf-parse.c	(revision 166792)
+++ java/jcf-parse.c	(working copy)
@@ -27,6 +27,7 @@ the Free Software Foundation; either ver
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "obstack.h"
 #include "flags.h"
Index: java/expr.c
===================================================================
--- java/expr.c	(revision 166792)
+++ java/expr.c	(working copy)
@@ -27,6 +27,7 @@ the Free Software Foundation; either ver
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "flags.h"
 #include "java-tree.h"
Index: target.def
===================================================================
--- target.def	(revision 166792)
+++ target.def	(working copy)
@@ -1890,8 +1890,9 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 (pass_by_reference,
  "",
  bool,
- (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
- hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
+ (/* CUMULATIVE_ARGS* */ void *cum, enum machine_mode mode,
+  const_tree type, bool named),
+ hook_bool_voidptr_mode_tree_bool_false)
 
 DEFHOOK
 (expand_builtin_saveregs,
@@ -1903,15 +1904,15 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK
 (setup_incoming_varargs,
  "",
- void, (CUMULATIVE_ARGS *args_so_far, enum machine_mode mode, tree type,
-	int *pretend_args_size, int second_time),
+ void, (/* CUMULATIVE_ARGS* */ void *args_so_far, enum machine_mode mode,
+	tree type, int *pretend_args_size, int second_time),
  default_setup_incoming_varargs)
 
 DEFHOOK
 (strict_argument_naming,
  "",
- bool, (CUMULATIVE_ARGS *ca),
- hook_bool_CUMULATIVE_ARGS_false)
+ bool, (/* CUMULATIVE_ARGS* */ void *ca),
+ hook_bool_voidptr_false)
 
 /* Returns true if we should use
    targetm.calls.setup_incoming_varargs() and/or
@@ -1919,7 +1920,7 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK
 (pretend_outgoing_varargs_named,
  "",
- bool, (CUMULATIVE_ARGS *ca),
+ bool, (/* CUMULATIVE_ARGS* */ void *ca),
  default_pretend_outgoing_varargs_named)
 
 /* Given a complex type T, return true if a parameter of type T
@@ -1946,8 +1947,9 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 (callee_copies,
  "",
  bool,
- (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
- hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
+ (/* CUMULATIVE_ARGS* */ void *cum, enum machine_mode mode, const_tree type,
+  bool named),
+ hook_bool_voidptr_mode_tree_bool_false)
 
 /* Return zero for arguments passed entirely on the stack or entirely
    in registers.  If passed in both, return the number of bytes passed
@@ -1955,8 +1957,9 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK
 (arg_partial_bytes,
  "",
- int, (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, bool named),
- hook_int_CUMULATIVE_ARGS_mode_tree_bool_0)
+ int, (/* CUMULATIVE_ARGS* */ void *cum, enum machine_mode mode, tree type,
+       bool named),
+ hook_int_voidptr_mode_tree_bool_0)
 
 /* Update the state in CA to advance past an argument in the
    argument list.  The values MODE, TYPE, and NAMED describe that
@@ -1966,7 +1969,8 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 (function_arg_advance,
  "",
  void,
- (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, bool named),
+ (/* CUMULATIVE_ARGS* */ void *ca, enum machine_mode mode, const_tree type,
+  bool named),
  default_function_arg_advance)
 
 /* Return zero if the argument described by the state of CA should
@@ -1977,7 +1981,7 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK_UNDOC
 (function_arg,
  "",
- rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
+ rtx, (/* CUMULATIVE_ARGS* */ void *ca, enum machine_mode mode, const_tree type,
        bool named),
  default_function_arg)
 
@@ -1987,8 +1991,8 @@ HOOK_VECTOR (TARGET_CALLS, calls)
 DEFHOOK_UNDOC
 (function_incoming_arg,
  "",
- rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
-       bool named),
+ rtx, (/* CUMULATIVE_ARGS* */ void *ca, enum machine_mode mode,
+       const_tree type, bool named),
  default_function_incoming_arg)
 
 /* Return the diagnostic message string if function without a prototype
Index: target.h
===================================================================
--- target.h	(revision 166792)
+++ target.h	(working copy)
@@ -49,7 +49,6 @@
 #ifndef GCC_TARGET_H
 #define GCC_TARGET_H
 
-#include "tm.h"
 #include "insn-modes.h"
 
 /* Types used by the record_gcc_switches() target function.  */
Index: expr.c
===================================================================
--- expr.c	(revision 166792)
+++ expr.c	(working copy)
@@ -8437,7 +8437,7 @@ expand_expr_real_1 (tree exp, rtx target
 	    int nregs = hard_regno_nregs[i][GET_MODE (decl_rtl)];
 	    while (nregs)
 	      {
-		SET_HARD_REG_BIT (crtl->asm_clobbers, i);
+		SET_HARD_REG_BIT (ctmrtl->asm_clobbers, i);
 		i++;
 		nregs--;
 	      }
Index: fortran/trans-types.c
===================================================================
--- fortran/trans-types.c	(revision 166792)
+++ fortran/trans-types.c	(working copy)
@@ -26,6 +26,7 @@ Software Foundation; either version 3, o
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "langhooks.h"	/* For iso-c-bindings.def.  */
 #include "target.h"
Index: function.c
===================================================================
--- function.c	(revision 166792)
+++ function.c	(working copy)
@@ -215,6 +215,7 @@ free_after_compilation (struct function 
     free (crtl->emit.regno_pointer_align);
 
   memset (crtl, 0, sizeof (struct rtl_data));
+  memset (ctmrtl, 0, sizeof (struct rtl_tm_data));
   f->eh = NULL;
   f->machine = NULL;
   f->cfg = NULL;
@@ -3463,7 +3464,7 @@ assign_parms (tree fndecl)
   /* For stdarg.h function, save info about
      regs and stack space used by the named args.  */
 
-  crtl->args.info = all.args_so_far;
+  ctmrtl->args_info = all.args_so_far;
 
   /* Set the rtx used for the function return value.  Put this in its
      own variable so any optimizers that need this information don't have
Index: function.h
===================================================================
--- function.h	(revision 166792)
+++ function.h	(working copy)
@@ -25,8 +25,9 @@ Software Foundation; either version 3, o
 #include "tree.h"
 #include "hashtab.h"
 #include "vecprim.h"
-#include "tm.h"		/* For CUMULATIVE_ARGS.  */
+#ifdef GCC_TM_H
 #include "hard-reg-set.h"
+#endif /* GCC_TM_H */
 
 /* Stack of pending (incomplete) sequences saved by `start_sequence'.
    Each element describes one pending sequence.
@@ -208,10 +209,6 @@ struct GTY(()) incoming_args {
      anonymous arg can be found, if there is one.  */
   rtx arg_offset_rtx;
 
-  /* Quantities of various kinds of registers
-     used for the current function's args.  */
-  CUMULATIVE_ARGS info;
-
   /* The arg pointer hard register, or the pseudo into which it was copied.  */
   rtx internal_arg_pointer;
 };
@@ -438,6 +435,15 @@ struct GTY(()) rtl_data {
      TREE_NOTHROW (current_function_decl) it is set even for overwritable
      function where currently compiled version of it is nothrow.  */
   bool nothrow;
+};
+
+#ifdef GCC_TM_H
+/* Datastructures maintained for currently processed function in RTL form,
+   which require inclusion of tm.h .  */
+struct GTY(()) rtl_tm_data {
+  /* Quantities of various kinds of registers
+     used for the current function's args.  */
+  CUMULATIVE_ARGS args_info;
 
   /* Like regs_ever_live, but 1 if a reg is set or clobbered from an
      asm.  Unlike regs_ever_live, elements of this array corresponding
@@ -445,6 +451,7 @@ struct GTY(()) rtl_data {
      sets them.  */
   HARD_REG_SET asm_clobbers;
 };
+#endif /* GCC_TM_H */
 
 #define return_label (crtl->x_return_label)
 #define naked_return_label (crtl->x_naked_return_label)
@@ -462,11 +469,13 @@ struct GTY(()) rtl_data {
 #define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap)
 
 extern GTY(()) struct rtl_data x_rtl;
+extern GTY(()) struct rtl_tm_data x_tm_rtl;
 
 /* Accessor to RTL datastructures.  We keep them statically allocated now since
    we never keep multiple functions.  For threaded compiler we might however
    want to do differently.  */
 #define crtl (&x_rtl)
+#define ctmrtl (&x_tm_rtl)
 
 struct GTY(()) stack_usage
 {
@@ -751,10 +760,12 @@ extern const char *current_function_name
 
 extern void do_warn_unused_parameter (tree);
 
+#ifdef GCC_TM_H
 extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
 			       tree, bool);
 extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode,
 				     tree, bool);
+#endif /* GCC_TM_H */
 
 extern void used_types_insert (tree);
 
Index: emit-rtl.c
===================================================================
--- emit-rtl.c	(revision 166792)
+++ emit-rtl.c	(working copy)
@@ -78,6 +78,7 @@ enum machine_mode ptr_mode;	/* Mode whos
 /* Datastructures maintained for currently processed function in RTL form.  */
 
 struct rtl_data x_rtl;
+struct rtl_tm_data x_tm_rtl;
 
 /* Indexed by pseudo register number, gives the rtx for that pseudo.
    Allocated in parallel with regno_pointer_align.
Index: ira.c
===================================================================
--- ira.c	(revision 166792)
+++ ira.c	(working copy)
@@ -1328,7 +1328,7 @@ compute_regs_asm_clobbered (void)
 		      + hard_regno_nregs[dregno][mode] - 1;
 
 		    for (i = dregno; i <= end; ++i)
-		      SET_HARD_REG_BIT(crtl->asm_clobbers, i);
+		      SET_HARD_REG_BIT(ctmrtl->asm_clobbers, i);
 		  }
 	      }
 	}
@@ -1374,7 +1374,7 @@ ira_setup_eliminable_regset (void)
 	= (! targetm.can_eliminate (eliminables[i].from, eliminables[i].to)
 	   || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
 
-      if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, eliminables[i].from))
+      if (!TEST_HARD_REG_BIT (ctmrtl->asm_clobbers, eliminables[i].from))
 	{
 	    SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
 
@@ -1388,7 +1388,7 @@ ira_setup_eliminable_regset (void)
 	df_set_regs_ever_live (eliminables[i].from, true);
     }
 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
-  if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
+  if (!TEST_HARD_REG_BIT (ctmrtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
     {
       SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
       if (need_fp)
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 166792)
+++ config/arm/arm.c	(working copy)
@@ -162,11 +162,9 @@ static rtx arm_expand_unop_builtin (enum
 static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
 static void emit_constant_insn (rtx cond, rtx pattern);
 static rtx emit_set_insn (rtx, rtx);
-static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
-				  tree, bool);
-static rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
-			     const_tree, bool);
-static void arm_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+static int arm_arg_partial_bytes (void *, enum machine_mode, tree, bool);
+static rtx arm_function_arg (void *, enum machine_mode, const_tree, bool);
+static void arm_function_arg_advance (void *, enum machine_mode,
 				      const_tree, bool);
 static rtx aapcs_allocate_return_reg (enum machine_mode, const_tree,
 				      const_tree);
@@ -183,9 +181,9 @@ static void arm_encode_section_info (tre
 static void arm_file_end (void);
 static void arm_file_start (void);
 
-static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
+static void arm_setup_incoming_varargs (void *, enum machine_mode,
 					tree, int *, int);
-static bool arm_pass_by_reference (CUMULATIVE_ARGS *,
+static bool arm_pass_by_reference (void *,
 				   enum machine_mode, const_tree, bool);
 static bool arm_promote_prototypes (const_tree);
 static bool arm_default_short_enums (void);
@@ -4555,9 +4553,10 @@ arm_needs_doubleword_align (enum machine
    indeed make it pass in the stack if necessary).  */
 
 static rtx
-arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+arm_function_arg (void *pcum_v, enum machine_mode mode,
 		  const_tree type, bool named)
 {
+  CUMULATIVE_ARGS *pcum = (CUMULATIVE_ARGS *) pcum_v;
   int nregs;
 
   /* Handle the special case quickly.  Pick an arbitrary value for op2 of
@@ -4607,9 +4606,11 @@ arm_function_arg (CUMULATIVE_ARGS *pcum,
 }
 
 static int
-arm_arg_partial_bytes (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+arm_arg_partial_bytes (void *pcum_v, enum machine_mode mode,
 		       tree type, bool named)
 {
+  CUMULATIVE_ARGS *pcum = (CUMULATIVE_ARGS *) pcum_v;
+
   int nregs = pcum->nregs;
 
   if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
@@ -4634,9 +4635,11 @@ arm_arg_partial_bytes (CUMULATIVE_ARGS *
    (TYPE is null for libcalls where that information may not be available.)  */
 
 static void
-arm_function_arg_advance (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+arm_function_arg_advance (void *pcum_v, enum machine_mode mode,
 			  const_tree type, bool named)
 {
+  CUMULATIVE_ARGS *pcum = (CUMULATIVE_ARGS *) pcum_v;
+
   if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL)
     {
       aapcs_layout_arg (pcum, mode, type, named);
@@ -4670,7 +4673,7 @@ arm_function_arg_advance (CUMULATIVE_ARG
    extension to the ARM ABI.  */
 
 static bool
-arm_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+arm_pass_by_reference (void *cum ATTRIBUTE_UNUSED,
 		       enum machine_mode mode ATTRIBUTE_UNUSED,
 		       const_tree type, bool named ATTRIBUTE_UNUSED)
 {
@@ -5241,7 +5244,7 @@ thumb_find_work_register (unsigned long 
   if (! cfun->machine->uses_anonymous_args
       && crtl->args.size >= 0
       && crtl->args.size <= (LAST_ARG_REGNUM * UNITS_PER_WORD)
-      && crtl->args.info.nregs < 4)
+      && ctmrtl->args_info.nregs < 4)
     return LAST_ARG_REGNUM;
 
   /* Otherwise look for a call-saved register that is going to be pushed.  */
@@ -21561,12 +21564,13 @@ arm_output_load_gr (rtx *operands)
    that way.  */
 
 static void
-arm_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
+arm_setup_incoming_varargs (void *pcum_v,
 			    enum machine_mode mode,
 			    tree type,
 			    int *pretend_size,
 			    int second_time ATTRIBUTE_UNUSED)
 {
+  CUMULATIVE_ARGS *pcum = (CUMULATIVE_ARGS *) pcum_v;
   int nregs;
   
   cfun->machine->uses_anonymous_args = 1;

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-16 10:12       ` Joern Rennecke
@ 2010-11-16 15:43         ` Ian Lance Taylor
  2010-11-16 16:14           ` Nathan Froyd
                             ` (3 more replies)
  0 siblings, 4 replies; 24+ messages in thread
From: Ian Lance Taylor @ 2010-11-16 15:43 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Joseph S. Myers, gcc

Joern Rennecke <amylaar@spamcop.net> writes:

> Before I go and make all these target changes & test them, is there at
> least agreemwent that this is the right approach, i.e replacing
> CUMULATIVE_ARG *
> with void *, and splitting up x_rtl into two variables.

I don't know how we want to get there, but it seems to me that the place
we want to end up is with the target hooks defined to take an argument
of type struct cumulative_args * (or a better name if we can think of
one).  We could consider moving the struct definition into CPU.c, and
having the target structure just report the size, or perhaps a combined
allocation/INIT_CUMULATIVE_ARGS function.

Ian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-16 15:43         ` Ian Lance Taylor
@ 2010-11-16 16:14           ` Nathan Froyd
  2010-11-16 17:34           ` Joern Rennecke
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 24+ messages in thread
From: Nathan Froyd @ 2010-11-16 16:14 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joern Rennecke, Joseph S. Myers, gcc

On Tue, Nov 16, 2010 at 06:23:32AM -0800, Ian Lance Taylor wrote:
> Joern Rennecke <amylaar@spamcop.net> writes:
> > Before I go and make all these target changes & test them, is there at
> > least agreemwent that this is the right approach, i.e replacing
> > CUMULATIVE_ARG *
> > with void *, and splitting up x_rtl into two variables.
> 
> I don't know how we want to get there, but it seems to me that the place
> we want to end up is with the target hooks defined to take an argument
> of type struct cumulative_args * (or a better name if we can think of
> one).  We could consider moving the struct definition into CPU.c, and
> having the target structure just report the size, or perhaps a combined
> allocation/INIT_CUMULATIVE_ARGS function.

FWIW, this is basically what I proposed here:

http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02527.html

I have gotten stalled on the INIT_* macros because the documentation and
the practices of individual backends do not seem to agree and I have not
taken the time to sit down and hammer out agreement.  (I don't think
attempting hookization of those macros would be appropriate for stage
3.)  I was a little uncertain how to handle the allocation issues; I
think specifying that the INIT_* hooks allocate them from a known place
(heap, obstack, or alloc_pool) is probably sufficient.

-Nathan

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-16 15:43         ` Ian Lance Taylor
  2010-11-16 16:14           ` Nathan Froyd
@ 2010-11-16 17:34           ` Joern Rennecke
  2010-11-16 22:53           ` Joern Rennecke
  2010-11-17  0:36           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Joern Rennecke
  3 siblings, 0 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-16 17:34 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joseph S. Myers, gcc

Quoting Ian Lance Taylor <iant@google.com>:

> Joern Rennecke <amylaar@spamcop.net> writes:
>
>> Before I go and make all these target changes & test them, is there at
>> least agreemwent that this is the right approach, i.e replacing
>> CUMULATIVE_ARG *
>> with void *, and splitting up x_rtl into two variables.
>
> I don't know how we want to get there, but it seems to me that the place
> we want to end up is with the target hooks defined to take an argument
> of type struct cumulative_args * (or a better name if we can think of
> one).  We could consider moving the struct definition into CPU.c, and
> having the target structure just report the size, or perhaps a combined
> allocation/INIT_CUMULATIVE_ARGS function.

If every target defines struct cumulative_args, allocation is straightforward.
ctmrtl (or if you think a better name, propose one) is a macro for the
global variable x_tm_rtl, which is defined in target-oriented middle-end
code that includes tm.h .

What is not quite clear is what is to happen with the args member of x_rtl.
Should I remove the info member from struct incoming_args, and shift that
to x_tm_rtl, or should I rather move the entire args member of x_rtl to
x_tm_rtl?  The latter would mean that struct incoming_args would remain
intact - but OTOH more churn in config/*/*, because every access to crtl->args
will have to be changed.

Or maybe we should leave the target-specific stuff in x_rtl / crtl and
instead move out the stuff that emit-rtl.h makes visible to non-rtl code,
e.g. x_first_insn, x_last_insn ...

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: RFC: semi-automatic hookization
  2010-11-16 15:43         ` Ian Lance Taylor
  2010-11-16 16:14           ` Nathan Froyd
  2010-11-16 17:34           ` Joern Rennecke
@ 2010-11-16 22:53           ` Joern Rennecke
  2010-11-17  0:36           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Joern Rennecke
  3 siblings, 0 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-16 22:53 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joseph S. Myers, gcc

Quoting Ian Lance Taylor <iant@google.com>:

> Joern Rennecke <amylaar@spamcop.net> writes:
>
>> Before I go and make all these target changes & test them, is there at
>> least agreemwent that this is the right approach, i.e replacing
>> CUMULATIVE_ARG *
>> with void *, and splitting up x_rtl into two variables.
>
> I don't know how we want to get there, but it seems to me that the place
> we want to end up is with the target hooks defined to take an argument
> of type struct cumulative_args * (or a better name if we can think of
> one).  We could consider moving the struct definition into CPU.c, and
> having the target structure just report the size, or perhaps a combined
> allocation/INIT_CUMULATIVE_ARGS function.
>
> Ian
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-16 15:43         ` Ian Lance Taylor
                             ` (2 preceding siblings ...)
  2010-11-16 22:53           ` Joern Rennecke
@ 2010-11-17  0:36           ` Joern Rennecke
  2010-11-17  2:04             ` Ian Lance Taylor
  3 siblings, 1 reply; 24+ messages in thread
From: Joern Rennecke @ 2010-11-17  0:36 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joseph S. Myers, gcc

Quoting Ian Lance Taylor <iant@google.com>:

> Joern Rennecke <amylaar@spamcop.net> writes:
>
>> Before I go and make all these target changes & test them, is there at
>> least agreemwent that this is the right approach, i.e replacing
>> CUMULATIVE_ARG *
>> with void *, and splitting up x_rtl into two variables.
>
> I don't know how we want to get there, but it seems to me that the place
> we want to end up is with the target hooks defined to take an argument
> of type struct cumulative_args * (or a better name if we can think of
> one).

Actually, this doesn't work, because then different target vectors have
different types.  You might get away with it now, but LTO on a multi-target
compiler would fail.

I think we should just
typedef void *cumulative_args_t;

and use that for our hooks.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17  0:36           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Joern Rennecke
@ 2010-11-17  2:04             ` Ian Lance Taylor
  2010-11-17  3:04               ` Paolo Bonzini
  0 siblings, 1 reply; 24+ messages in thread
From: Ian Lance Taylor @ 2010-11-17  2:04 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gcc

Joern Rennecke <amylaar@spamcop.net> writes:

> Quoting Ian Lance Taylor <iant@google.com>:
>
>> Joern Rennecke <amylaar@spamcop.net> writes:
>>
>>> Before I go and make all these target changes & test them, is there at
>>> least agreemwent that this is the right approach, i.e replacing
>>> CUMULATIVE_ARG *
>>> with void *, and splitting up x_rtl into two variables.
>>
>> I don't know how we want to get there, but it seems to me that the place
>> we want to end up is with the target hooks defined to take an argument
>> of type struct cumulative_args * (or a better name if we can think of
>> one).
>
> Actually, this doesn't work, because then different target vectors have
> different types.  You might get away with it now, but LTO on a multi-target
> compiler would fail.

Good point.

> I think we should just
> typedef void *cumulative_args_t;
>
> and use that for our hooks.

Another area where we can do something much nicer when we move to C++.

Ian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17  2:04             ` Ian Lance Taylor
@ 2010-11-17  3:04               ` Paolo Bonzini
  2010-11-17  3:22                 ` Joern Rennecke
  0 siblings, 1 reply; 24+ messages in thread
From: Paolo Bonzini @ 2010-11-17  3:04 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joern Rennecke, gcc

On 11/16/2010 10:17 PM, Ian Lance Taylor wrote:
>>> I don't know how we want to get there, but it seems to me that the place
>>> we want to end up is with the target hooks defined to take an argument
>>> of type struct cumulative_args * (or a better name if we can think of
>>> one).
>>
>> Actually, this doesn't work, because then different target vectors have
>> different types.  You might get away with it now, but LTO on a multi-target
>> compiler would fail.
>
> Good point.
>
>> I think we should just
>> typedef void *cumulative_args_t;
>>
>> and use that for our hooks.
>
> Another area where we can do something much nicer when we move to C++.

This something could be something like target_i386::cumulative_args, 
implemented e.g. using the curiously recurring template pattern 
(http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).

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.

Paolo

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17  3:04               ` Paolo Bonzini
@ 2010-11-17  3:22                 ` Joern Rennecke
  2010-11-17  3:45                   ` Ian Lance Taylor
  0 siblings, 1 reply; 24+ messages in thread
From: Joern Rennecke @ 2010-11-17  3:22 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Ian Lance Taylor, gcc, Nathan Froyd

Quoting Paolo Bonzini <bonzini@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.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17  3:22                 ` Joern Rennecke
@ 2010-11-17  3:45                   ` Ian Lance Taylor
  2010-11-17  4:06                     ` Paolo Bonzini
  0 siblings, 1 reply; 24+ messages in thread
From: Ian Lance Taylor @ 2010-11-17  3:45 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Paolo Bonzini, gcc, Nathan Froyd

Joern Rennecke <amylaar@spamcop.net> writes:

> 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...

In C++ we would use a pure abstract base class in the target hooks and
the targets would have to provide an implementation for the base class.

Ian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17  3:45                   ` Ian Lance Taylor
@ 2010-11-17  4:06                     ` Paolo Bonzini
  2010-11-17 11:58                       ` Nathan Froyd
  0 siblings, 1 reply; 24+ messages in thread
From: Paolo Bonzini @ 2010-11-17  4:06 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Joern Rennecke, gcc, Nathan Froyd

On 11/17/2010 03:10 AM, Ian Lance Taylor wrote:
> Joern Rennecke<amylaar@spamcop.net>  writes:
>> 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. [...]
>> Converting an empty base class to a derived class is not really
>> safer than converting a void * to a struct pointer.

True, but you can hide that cast in a base class.  For example you can 
use a hierarchy

     Target                           // abstract base
         TargetImplBase<TargetI386>   // provides strong typing
             TargetI386               // actual implementation

The Target class would indeed take a void *, but the middle class would 
let TargetI386 think in terms of TargetI386::CumulativeArgs with 
something like

     void f(void *x) {
         // T needs to provide void T::f(T::CumulativeArgs *)
         f(static_cast<T::CumulativeArgs *> (x));
     }

The most similar thing in C (though not suitable for multitarget) is a 
struct, which is why I suggest using that now rather than void * (which 
would be an implementation detail).

Paolo

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17  4:06                     ` Paolo Bonzini
@ 2010-11-17 11:58                       ` Nathan Froyd
  2010-11-17 14:34                         ` Joern Rennecke
  2010-11-17 15:25                         ` Ian Lance Taylor
  0 siblings, 2 replies; 24+ messages in thread
From: Nathan Froyd @ 2010-11-17 11:58 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Ian Lance Taylor, Joern Rennecke, gcc

On Wed, Nov 17, 2010 at 03:40:39AM +0100, Paolo Bonzini wrote:
> True, but you can hide that cast in a base class.  For example you
> can use a hierarchy
> 
>     Target                           // abstract base
>         TargetImplBase<TargetI386>   // provides strong typing
>             TargetI386               // actual implementation
> 
> The Target class would indeed take a void *, but the middle class
> would let TargetI386 think in terms of TargetI386::CumulativeArgs
> with something like
> 
>     void f(void *x) {
>         // T needs to provide void T::f(T::CumulativeArgs *)
>         f(static_cast<T::CumulativeArgs *> (x));
>     }
> 
> The most similar thing in C (though not suitable for multitarget) is
> a struct, which is why I suggest using that now rather than void *
> (which would be an implementation detail).

I am admittedly a C++ newbie; the first thing I thought of was:

class gcc::cumulative_args {
  virtual void advance (...) = 0;
  virtual rtx arg (...) = 0;
  virtual rtx incoming_arg (...) { return this->arg (...); };
  virtual int arg_partial_bytes (...) = 0;
  // ...and so on for many of the hooks that take CUMULATIVE_ARGS *
  // possibly with default implementations instead of pure virtual
  // functions.
};

class i386::cumulative_args : gcc::cumulative_args {
  // concrete implementations of virtual functions
};

// the hook interface is then solely for the backend to return
// `cumulative_args *' things (the current INIT_*_ARGS macros), which
// are then manipulated via the virtual functions above.

AFAICS, this eliminates the casting issues Joern described.  What are
the advantages of the scheme you describe above?  (Honest question.)  Or
are we talking about the same thing in slightly different terms?

-Nathan

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17 11:58                       ` Nathan Froyd
@ 2010-11-17 14:34                         ` Joern Rennecke
  2010-11-17 16:01                           ` P.S.: Re: CUMULATIVE_ARGS in hooks Joern Rennecke
  2010-11-17 19:20                           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Nathan Froyd
  2010-11-17 15:25                         ` Ian Lance Taylor
  1 sibling, 2 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-17 14:34 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Paolo Bonzini, Ian Lance Taylor, gcc

Quoting Nathan Froyd <froydnj@codesourcery.com>:

> I am admittedly a C++ newbie; the first thing I thought of was:
>
> class gcc::cumulative_args {
>   virtual void advance (...) = 0;
>   virtual rtx arg (...) = 0;
>   virtual rtx incoming_arg (...) { return this->arg (...); };
>   virtual int arg_partial_bytes (...) = 0;
>   // ...and so on for many of the hooks that take CUMULATIVE_ARGS *
>   // possibly with default implementations instead of pure virtual
>   // functions.
> };

Trying to put a target-derived object of that into struct rtl_data would
be nonsentical.  You might store a pointer, of course.
But at any rate, the member function implementations would not be part
of the globally-visible target vector.  They are in a smaller vector, and
only the pieces of the middle end that deal with argument passing get to
see them.
Does that mean you acknowledge that we shouldn't have CUMULATIVE_ARGS
taking hooks in the global target vector?

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17 11:58                       ` Nathan Froyd
  2010-11-17 14:34                         ` Joern Rennecke
@ 2010-11-17 15:25                         ` Ian Lance Taylor
  2010-11-17 15:45                           ` Joern Rennecke
  1 sibling, 1 reply; 24+ messages in thread
From: Ian Lance Taylor @ 2010-11-17 15:25 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Paolo Bonzini, Joern Rennecke, gcc

Nathan Froyd <froydnj@codesourcery.com> writes:

> On Wed, Nov 17, 2010 at 03:40:39AM +0100, Paolo Bonzini wrote:
>> True, but you can hide that cast in a base class.  For example you
>> can use a hierarchy
>> 
>>     Target                           // abstract base
>>         TargetImplBase<TargetI386>   // provides strong typing
>>             TargetI386               // actual implementation
>> 
>> The Target class would indeed take a void *, but the middle class
>> would let TargetI386 think in terms of TargetI386::CumulativeArgs
>> with something like
>> 
>>     void f(void *x) {
>>         // T needs to provide void T::f(T::CumulativeArgs *)
>>         f(static_cast<T::CumulativeArgs *> (x));
>>     }
>> 
>> The most similar thing in C (though not suitable for multitarget) is
>> a struct, which is why I suggest using that now rather than void *
>> (which would be an implementation detail).
>
> I am admittedly a C++ newbie; the first thing I thought of was:
>
> class gcc::cumulative_args {
>   virtual void advance (...) = 0;
>   virtual rtx arg (...) = 0;
>   virtual rtx incoming_arg (...) { return this->arg (...); };
>   virtual int arg_partial_bytes (...) = 0;
>   // ...and so on for many of the hooks that take CUMULATIVE_ARGS *
>   // possibly with default implementations instead of pure virtual
>   // functions.
> };
>
> class i386::cumulative_args : gcc::cumulative_args {
>   // concrete implementations of virtual functions
> };
>
> // the hook interface is then solely for the backend to return
> // `cumulative_args *' things (the current INIT_*_ARGS macros), which
> // are then manipulated via the virtual functions above.
>
> AFAICS, this eliminates the casting issues Joern described.  What are
> the advantages of the scheme you describe above?  (Honest question.)  Or
> are we talking about the same thing in slightly different terms?

The scheme that Paolo describes avoids virtual functions.  But for this
usage I personally would prefer virtual functions, since there is no
efficiency cost compared to a target hook.

Ian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17 15:25                         ` Ian Lance Taylor
@ 2010-11-17 15:45                           ` Joern Rennecke
  0 siblings, 0 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-17 15:45 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Nathan Froyd, Paolo Bonzini, gcc

Quoting Ian Lance Taylor <iant@google.com>:

> The scheme that Paolo describes avoids virtual functions.  But for this
> usage I personally would prefer virtual functions, since there is no
> efficiency cost compared to a target hook.

Well, actually, there is: you first fetch the object pointer, then you
find the vtable pointer, and then you load the function pointer.

With the target hook, you load the function pointer.

And with the function-name-valued macro, you directly call the function.

Does it matter?  I don't know, but I would guess it doesn't.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* P.S.: Re: CUMULATIVE_ARGS in hooks
  2010-11-17 14:34                         ` Joern Rennecke
@ 2010-11-17 16:01                           ` Joern Rennecke
  2010-11-17 19:20                           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Nathan Froyd
  1 sibling, 0 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-17 16:01 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Paolo Bonzini, Ian Lance Taylor, gcc

[-- Attachment #1: Type: text/plain, Size: 408 bytes --]

Quoting Joern Rennecke <amylaar@spamcop.net>:

> Does that mean you acknowledge that we shouldn't have CUMULATIVE_ARGS
> taking hooks in the global target vector?

FWIW, I think the attached patch would be approximately what it takes to
remove the CUMULATIVE_ARGS taking hooks from the global target vector
and put them into a separate vector only to be seen by a select few files.
Not tested yet, though.



[-- Attachment #2: pr46500-split-20101117-1147-nf --]
[-- Type: text/plain, Size: 47399 bytes --]

Index: targhooks.c
===================================================================
--- targhooks.c	(revision 166860)
+++ targhooks.c	(working copy)
@@ -60,6 +60,7 @@ Software Foundation; either version 3, o
 #include "toplev.h"
 #include "function.h"
 #include "target.h"
+#include "target-internal.h"
 #include "tm_p.h"
 #include "target-def.h"
 #include "ggc.h"
@@ -194,7 +195,7 @@ hook_bool_CUMULATIVE_ARGS_false (CUMULAT
 bool
 default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
 {
-  return (targetm.calls.setup_incoming_varargs
+  return (target_internalm.setup_incoming_varargs
 	  != default_setup_incoming_varargs);
 }
 
Index: c-family/c-opts.c
===================================================================
--- c-family/c-opts.c	(revision 166860)
+++ c-family/c-opts.c	(working copy)
@@ -23,6 +23,7 @@ Software Foundation; either version 3, o
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "tm.h"
 #include "c-common.h"
 #include "c-pragma.h"
 #include "flags.h"
Index: java/expr.c
===================================================================
--- java/expr.c	(revision 166860)
+++ java/expr.c	(working copy)
@@ -28,6 +28,7 @@ the Free Software Foundation; either ver
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "tm.h"
 #include "flags.h"
 #include "java-tree.h"
 #include "javaop.h"
Index: target.def
===================================================================
--- target.def	(revision 166860)
+++ target.def	(working copy)
@@ -1883,45 +1883,12 @@ HOOK_VECTOR (TARGET_CALLS, calls)
  bool, (const_tree type),
  hook_bool_const_tree_false)
 
-/* Return true if a parameter must be passed by reference.  TYPE may
-   be null if this is a libcall.  CA may be null if this query is
-   from __builtin_va_arg.  */
-DEFHOOK
-(pass_by_reference,
- "",
- bool,
- (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
- hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
-
 DEFHOOK
 (expand_builtin_saveregs,
  "",
  rtx, (void),
  default_expand_builtin_saveregs)
 
-/* Returns pretend_argument_size.  */
-DEFHOOK
-(setup_incoming_varargs,
- "",
- void, (CUMULATIVE_ARGS *args_so_far, enum machine_mode mode, tree type,
-	int *pretend_args_size, int second_time),
- default_setup_incoming_varargs)
-
-DEFHOOK
-(strict_argument_naming,
- "",
- bool, (CUMULATIVE_ARGS *ca),
- hook_bool_CUMULATIVE_ARGS_false)
-
-/* Returns true if we should use
-   targetm.calls.setup_incoming_varargs() and/or
-   targetm.calls.strict_argument_naming().  */
-DEFHOOK
-(pretend_outgoing_varargs_named,
- "",
- bool, (CUMULATIVE_ARGS *ca),
- default_pretend_outgoing_varargs_named)
-
 /* Given a complex type T, return true if a parameter of type T
    should be passed as two scalars.  */
 DEFHOOK
@@ -1939,58 +1906,6 @@ HOOK_VECTOR (TARGET_CALLS, calls)
  bool, (enum machine_mode mode, const_tree type),
  must_pass_in_stack_var_size_or_pad)
 
-/* Return true if type TYPE, mode MODE, which is passed by reference,
-   should have the object copy generated by the callee rather than
-   the caller.  It is never called for TYPE requiring constructors.  */
-DEFHOOK
-(callee_copies,
- "",
- bool,
- (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
- hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
-
-/* Return zero for arguments passed entirely on the stack or entirely
-   in registers.  If passed in both, return the number of bytes passed
-   in registers; the balance is therefore passed on the stack.  */
-DEFHOOK
-(arg_partial_bytes,
- "",
- int, (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, bool named),
- hook_int_CUMULATIVE_ARGS_mode_tree_bool_0)
-
-/* Update the state in CA to advance past an argument in the
-   argument list.  The values MODE, TYPE, and NAMED describe that
-   argument.  */
-/* ??? tm.texi still only describes the old macro.  */
-DEFHOOK_UNDOC
-(function_arg_advance,
- "",
- void,
- (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, bool named),
- default_function_arg_advance)
-
-/* Return zero if the argument described by the state of CA should
-   be placed on a stack, or a hard register in which to store the
-   argument.  The values MODE, TYPE, and NAMED describe that
-   argument.  */
-/* ??? tm.texi still only describes the old macro.  */
-DEFHOOK_UNDOC
-(function_arg,
- "",
- rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
-       bool named),
- default_function_arg)
-
-/* Likewise, but for machines with register windows.  Return the
-   location where the argument will appear to the callee.  */
-/* ??? tm.texi still only describes the old macro.  */
-DEFHOOK_UNDOC
-(function_incoming_arg,
- "",
- rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
-       bool named),
- default_function_incoming_arg)
-
 DEFHOOK
 (function_arg_boundary,
  "",
Index: target.h
===================================================================
--- target.h	(revision 166860)
+++ target.h	(working copy)
@@ -49,7 +49,6 @@
 #ifndef GCC_TARGET_H
 #define GCC_TARGET_H
 
-#include "tm.h"
 #include "insn-modes.h"
 
 /* Types used by the record_gcc_switches() target function.  */
Index: expr.c
===================================================================
--- expr.c	(revision 166860)
+++ expr.c	(working copy)
@@ -49,6 +49,7 @@ Software Foundation; either version 3, o
 #include "tree-pass.h"
 #include "tree-flow.h"
 #include "target.h"
+#include "target-internal.h"
 #include "timevar.h"
 #include "df.h"
 #include "diagnostic.h"
@@ -1238,14 +1239,14 @@ block_move_libcall_safe_for_call_parm (v
     for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
       {
 	enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
-	rtx tmp = targetm.calls.function_arg (&args_so_far, mode,
-					      NULL_TREE, true);
+	rtx tmp = target_internalm.function_arg (&args_so_far, mode,
+						 NULL_TREE, true);
 	if (!tmp || !REG_P (tmp))
 	  return false;
-	if (targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL, 1))
+	if (target_internalm.arg_partial_bytes (&args_so_far, mode, NULL, 1))
 	  return false;
-	targetm.calls.function_arg_advance (&args_so_far, mode,
-					    NULL_TREE, true);
+	target_internalm.function_arg_advance (&args_so_far, mode,
+					       NULL_TREE, true);
       }
   }
   return true;
Index: dse.c
===================================================================
--- dse.c	(revision 166860)
+++ dse.c	(working copy)
@@ -47,6 +47,7 @@ Software Foundation; either version 3, o
 #include "optabs.h"
 #include "dbgcnt.h"
 #include "target.h"
+#include "target-internal.h"
 
 /* This file contains three techniques for performing Dead Store
    Elimination (dse).
@@ -2322,7 +2323,7 @@ get_call_args (rtx call_insn, tree fn, r
     {
       enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
       rtx reg, link, tmp;
-      reg = targetm.calls.function_arg (&args_so_far, mode, NULL_TREE, true);
+      reg = target_internalm.function_arg (&args_so_far, mode, NULL_TREE, true);
       if (!reg || !REG_P (reg) || GET_MODE (reg) != mode
 	  || GET_MODE_CLASS (mode) != MODE_INT)
 	return false;
@@ -2356,7 +2357,8 @@ get_call_args (rtx call_insn, tree fn, r
       if (tmp)
 	args[idx] = tmp;
 
-      targetm.calls.function_arg_advance (&args_so_far, mode, NULL_TREE, true);
+      target_internalm.function_arg_advance (&args_so_far, mode, NULL_TREE,
+					     true);
     }
   if (arg != void_list_node || idx != nargs)
     return false;
Index: fortran/trans-types.c
===================================================================
--- fortran/trans-types.c	(revision 166860)
+++ fortran/trans-types.c	(working copy)
@@ -27,6 +27,7 @@ Software Foundation; either version 3, o
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
+#include "tm.h"
 #include "langhooks.h"	/* For iso-c-bindings.def.  */
 #include "target.h"
 #include "ggc.h"
Index: function.c
===================================================================
--- function.c	(revision 166860)
+++ function.c	(working copy)
@@ -57,6 +57,7 @@ Software Foundation; either version 3, o
 #include "integrate.h"
 #include "langhooks.h"
 #include "target.h"
+#include "target-internal.h"
 #include "cfglayout.h"
 #include "gimple.h"
 #include "tree-pass.h"
@@ -2106,7 +2107,7 @@ pass_by_reference (CUMULATIVE_ARGS *ca, 
 	}
     }
 
-  return targetm.calls.pass_by_reference (ca, mode, type, named_arg);
+  return target_internalm.pass_by_reference (ca, mode, type, named_arg);
 }
 
 /* Return true if TYPE, which is passed by reference, should be callee
@@ -2118,7 +2119,7 @@ reference_callee_copied (CUMULATIVE_ARGS
 {
   if (type && TREE_ADDRESSABLE (type))
     return false;
-  return targetm.calls.callee_copies (ca, mode, type, named_arg);
+  return target_internalm.callee_copies (ca, mode, type, named_arg);
 }
 
 /* Structures to communicate between the subroutines of assign_parms.
@@ -2291,7 +2292,7 @@ assign_parm_find_data_types (struct assi
     data->named_arg = 1;  /* No variadic parms.  */
   else if (DECL_CHAIN (parm))
     data->named_arg = 1;  /* Not the last non-variadic parm. */
-  else if (targetm.calls.strict_argument_naming (&all->args_so_far))
+  else if (target_internalm.strict_argument_naming (&all->args_so_far))
     data->named_arg = 1;  /* Only variadic ones are unnamed.  */
   else
     data->named_arg = 0;  /* Treat as variadic.  */
@@ -2356,7 +2357,7 @@ assign_parms_setup_varargs (struct assig
 {
   int varargs_pretend_bytes = 0;
 
-  targetm.calls.setup_incoming_varargs (&all->args_so_far,
+  target_internalm.setup_incoming_varargs (&all->args_so_far,
 					data->promoted_mode,
 					data->passed_type,
 					&varargs_pretend_bytes, no_rtl);
@@ -2385,10 +2386,11 @@ assign_parm_find_entry_rtl (struct assig
       return;
     }
 
-  entry_parm = targetm.calls.function_incoming_arg (&all->args_so_far,
-						    data->promoted_mode,
-						    data->passed_type,
-						    data->named_arg);
+  entry_parm
+    = target_internalm.function_incoming_arg (&all->args_so_far,
+					      data->promoted_mode,
+					      data->passed_type,
+					      data->named_arg);
 
   if (entry_parm == 0)
     data->promoted_mode = data->passed_mode;
@@ -2409,12 +2411,12 @@ assign_parm_find_entry_rtl (struct assig
 #endif
   if (!in_regs && !data->named_arg)
     {
-      if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far))
+      if (target_internalm.pretend_outgoing_varargs_named (&all->args_so_far))
 	{
-	  rtx tem;
-	  tem = targetm.calls.function_incoming_arg (&all->args_so_far,
-						     data->promoted_mode,
-						     data->passed_type, true);
+	  rtx tem
+	    = target_internalm.function_incoming_arg (&all->args_so_far,
+						      data->promoted_mode,
+						      data->passed_type, true);
 	  in_regs = tem != NULL;
 	}
     }
@@ -2429,10 +2431,10 @@ assign_parm_find_entry_rtl (struct assig
     {
       int partial;
 
-      partial = targetm.calls.arg_partial_bytes (&all->args_so_far,
-						 data->promoted_mode,
-						 data->passed_type,
-						 data->named_arg);
+      partial = target_internalm.arg_partial_bytes (&all->args_so_far,
+						    data->promoted_mode,
+						    data->passed_type,
+						    data->named_arg);
       data->partial = partial;
 
       /* The caller might already have allocated stack space for the
@@ -3363,8 +3365,9 @@ assign_parms (tree fndecl)
       set_decl_incoming_rtl (parm, data.entry_parm, data.passed_pointer);
 
       /* Update info on where next arg arrives in registers.  */
-      targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode,
-					  data.passed_type, data.named_arg);
+      target_internalm.function_arg_advance (&all.args_so_far,
+					     data.promoted_mode,
+					     data.passed_type, data.named_arg);
 
       assign_parm_adjust_stack_rtl (&data);
 
@@ -3553,8 +3556,9 @@ gimplify_parameters (void)
 	continue;
 
       /* Update info on where next arg arrives in registers.  */
-      targetm.calls.function_arg_advance (&all.args_so_far, data.promoted_mode,
-					  data.passed_type, data.named_arg);
+      target_internalm.function_arg_advance (&all.args_so_far,
+					     data.promoted_mode,
+					     data.passed_type, data.named_arg);
 
       /* ??? Once upon a time variable_size stuffed parameter list
 	 SAVE_EXPRs (amongst others) onto a pending sizes list.  This
Index: calls.c
===================================================================
--- calls.c	(revision 166860)
+++ calls.c	(working copy)
@@ -39,6 +39,7 @@ Software Foundation; either version 3, o
 #include "sbitmap.h"
 #include "langhooks.h"
 #include "target.h"
+#include "target-internal.h"
 #include "debug.h"
 #include "cgraph.h"
 #include "except.h"
@@ -228,7 +229,8 @@ prepare_call_address (tree fndecl, rtx f
    It is zero if this call doesn't want a structure value.
 
    NEXT_ARG_REG is the rtx that results from executing
-     targetm.calls.function_arg (&args_so_far, VOIDmode, void_type_node, true)
+     target_internalm.function_arg (&args_so_far, VOIDmode, void_type_node,
+				    true)
    just after all the args have had their registers assigned.
    This could be whatever you like, but normally it is the first
    arg-register beyond those used for args in this call,
@@ -1138,23 +1140,24 @@ initialize_argument_information (int num
       args[i].unsignedp = unsignedp;
       args[i].mode = mode;
 
-      args[i].reg = targetm.calls.function_arg (args_so_far, mode, type,
-						argpos < n_named_args);
+      args[i].reg = target_internalm.function_arg (args_so_far, mode, type,
+						   argpos < n_named_args);
 
       /* If this is a sibling call and the machine has register windows, the
 	 register window has to be unwinded before calling the routine, so
 	 arguments have to go into the incoming registers.  */
-      if (targetm.calls.function_incoming_arg != targetm.calls.function_arg)
+      if (target_internalm.function_incoming_arg
+	  != target_internalm.function_arg)
 	args[i].tail_call_reg
-	  = targetm.calls.function_incoming_arg (args_so_far, mode, type,
-						 argpos < n_named_args);
+	  = target_internalm.function_incoming_arg (args_so_far, mode, type,
+						    argpos < n_named_args);
       else
 	args[i].tail_call_reg = args[i].reg;
 
       if (args[i].reg)
 	args[i].partial
-	  = targetm.calls.arg_partial_bytes (args_so_far, mode, type,
-					     argpos < n_named_args);
+	  = target_internalm.arg_partial_bytes (args_so_far, mode, type,
+						argpos < n_named_args);
 
       args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
 
@@ -1204,8 +1207,8 @@ initialize_argument_information (int num
       /* Increment ARGS_SO_FAR, which has info about which arg-registers
 	 have been used, etc.  */
 
-      targetm.calls.function_arg_advance (args_so_far, TYPE_MODE (type),
-					  type, argpos < n_named_args);
+      target_internalm.function_arg_advance (args_so_far, TYPE_MODE (type),
+					     type, argpos < n_named_args);
     }
 }
 
@@ -2231,26 +2234,26 @@ expand_call (tree exp, rtx target, int i
   /* Now possibly adjust the number of named args.
      Normally, don't include the last named arg if anonymous args follow.
      We do include the last named arg if
-     targetm.calls.strict_argument_naming() returns nonzero.
+     target_internalm.strict_argument_naming() returns nonzero.
      (If no anonymous args follow, the result of list_length is actually
      one too large.  This is harmless.)
 
-     If targetm.calls.pretend_outgoing_varargs_named() returns
-     nonzero, and targetm.calls.strict_argument_naming() returns zero,
+     If target_internalm.pretend_outgoing_varargs_named() returns
+     nonzero, and target_internalm.strict_argument_naming() returns zero,
      this machine will be able to place unnamed args that were passed
      in registers into the stack.  So treat all args as named.  This
      allows the insns emitting for a specific argument list to be
      independent of the function declaration.
 
-     If targetm.calls.pretend_outgoing_varargs_named() returns zero,
+     If targetinternalm.pretend_outgoing_varargs_named() returns zero,
      we do not have any reliable way to pass unnamed args in
      registers, so we must force them into memory.  */
 
   if (type_arg_types != 0
-      && targetm.calls.strict_argument_naming (&args_so_far))
+      && target_internalm.strict_argument_naming (&args_so_far))
     ;
   else if (type_arg_types != 0
-	   && ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
+	   && ! targetinternalm.pretend_outgoing_varargs_named (&args_so_far))
     /* Don't include the last named arg.  */
     --n_named_args;
   else
@@ -2861,14 +2864,14 @@ expand_call (tree exp, rtx target, int i
       /* Set up next argument register.  For sibling calls on machines
 	 with register windows this should be the incoming register.  */
       if (pass == 0)
-	next_arg_reg = targetm.calls.function_incoming_arg (&args_so_far,
-							    VOIDmode,
-							    void_type_node,
-							    true);
+	next_arg_reg = target_internalm.function_incoming_arg (&args_so_far,
+							       VOIDmode,
+							       void_type_node,
+							       true);
       else
-	next_arg_reg = targetm.calls.function_arg (&args_so_far,
-						   VOIDmode, void_type_node,
-						   true);
+	next_arg_reg
+	  = target_internalm.function_arg (&args_so_far, VOIDmode,
+					   void_type_node, true);
 
       /* All arguments and registers used for the call must be set up by
 	 now!  */
@@ -3455,10 +3458,10 @@ emit_library_call_value_1 (int retval, r
       argvec[count].mode = Pmode;
       argvec[count].partial = 0;
 
-      argvec[count].reg = targetm.calls.function_arg (&args_so_far,
-						      Pmode, NULL_TREE, true);
-      gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode,
-						   NULL_TREE, 1) == 0);
+      argvec[count].reg
+	= target_internalm.function_arg (&args_so_far, Pmode, NULL_TREE, true);
+      gcc_assert (target_internalm.arg_partial_bytes (&args_so_far, Pmode,
+						      NULL_TREE, 1) == 0);
 
       locate_and_pad_parm (Pmode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -3472,7 +3475,8 @@ emit_library_call_value_1 (int retval, r
 	  || reg_parm_stack_space > 0)
 	args_size.constant += argvec[count].locate.size.constant;
 
-      targetm.calls.function_arg_advance (&args_so_far, Pmode, (tree) 0, true);
+      target_internalm.function_arg_advance (&args_so_far, Pmode, (tree) 0,
+					     true);
 
       count++;
     }
@@ -3531,11 +3535,11 @@ emit_library_call_value_1 (int retval, r
       argvec[count].value = val;
       argvec[count].mode = mode;
 
-      argvec[count].reg = targetm.calls.function_arg (&args_so_far, mode,
-						      NULL_TREE, true);
+      argvec[count].reg
+	= target_internalm.function_arg (&args_so_far, mode, NULL_TREE, true);
 
       argvec[count].partial
-	= targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1);
+	= target_internalm.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1);
 
       locate_and_pad_parm (mode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -3552,7 +3556,8 @@ emit_library_call_value_1 (int retval, r
 	  || reg_parm_stack_space > 0)
 	args_size.constant += argvec[count].locate.size.constant;
 
-      targetm.calls.function_arg_advance (&args_so_far, mode, (tree) 0, true);
+      target_internalm.function_arg_advance (&args_so_far, mode, (tree) 0,
+					     true);
     }
 
   /* If this machine requires an external definition for library
@@ -3868,8 +3873,8 @@ emit_library_call_value_1 (int retval, r
 	       build_function_type (tfom, NULL_TREE),
 	       original_args_size.constant, args_size.constant,
 	       struct_value_size,
-	       targetm.calls.function_arg (&args_so_far,
-					   VOIDmode, void_type_node, true),
+	       target_internalm.function_arg (&args_so_far,
+					      VOIDmode, void_type_node, true),
 	       valreg,
 	       old_inhibit_defer_pop + 1, call_fusage, flags, & args_so_far);
 
Index: genhooks.c
===================================================================
--- genhooks.c	(revision 166860)
+++ genhooks.c	(working copy)
@@ -34,6 +34,7 @@ #define DEFHOOK(NAME, DOC, TYPE, PARAMS,
 #define DEFHOOK_UNDOC(NAME, DOC, TYPE, PARAMS, INIT) \
   { "*", #TYPE, HOOK_PREFIX #NAME, #PARAMS, #INIT },
 #include "target.def"
+#include "target-internal.def"
 #undef DEFHOOK
 };
 
Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c	(revision 166860)
+++ config/alpha/alpha.c	(working copy)
@@ -11160,5 +11160,7 @@ #define TARGET_DEFAULT_TARGET_FLAGS \
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 \f
 #include "gt-alpha.h"
Index: config/frv/frv.c
===================================================================
--- config/frv/frv.c	(revision 166860)
+++ config/frv/frv.c	(working copy)
@@ -545,6 +545,8 @@ #define TARGET_DEFAULT_TARGET_FLAGS		\
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #define FRV_SYMBOL_REF_TLS_P(RTX) \
   (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
 
Index: config/s390/s390.c
===================================================================
--- config/s390/s390.c	(revision 166860)
+++ config/s390/s390.c	(working copy)
@@ -10660,4 +10660,6 @@ s390_loop_unroll_adjust (unsigned nunrol
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #include "gt-s390.h"
Index: config/m32c/m32c.c
===================================================================
--- config/m32c/m32c.c	(revision 166860)
+++ config/m32c/m32c.c	(working copy)
@@ -4850,4 +4850,6 @@ m32c_output_compare (rtx insn, rtx *oper
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #include "gt-m32c.h"
Index: config/spu/spu.c
===================================================================
--- config/spu/spu.c	(revision 166860)
+++ config/spu/spu.c	(working copy)
@@ -491,6 +491,8 @@ #define TARGET_ADDR_SPACE_LEGITIMATE_ADD
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 static void
 spu_option_init_struct (struct gcc_options *opts)
 {
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 166860)
+++ config/sparc/sparc.c	(working copy)
@@ -652,6 +652,8 @@ enum processor_type sparc_cpu;
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 /* Implement TARGET_HANDLE_OPTION.  */
 
 static bool
Index: config/mep/mep.c
===================================================================
--- config/mep/mep.c	(revision 166860)
+++ config/mep/mep.c	(working copy)
@@ -7459,4 +7459,6 @@ mep_asm_init_sections (void)
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #include "gt-mep.h"
Index: config/m32r/m32r.c
===================================================================
--- config/m32r/m32r.c	(revision 166860)
+++ config/m32r/m32r.c	(working copy)
@@ -208,6 +208,8 @@ static void m32r_trampoline_init (rtx, t
 #define TARGET_TRAMPOLINE_INIT m32r_trampoline_init
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Implement TARGET_HANDLE_OPTION.  */
 
Index: config/rx/rx.c
===================================================================
--- config/rx/rx.c	(revision 166860)
+++ config/rx/rx.c	(working copy)
@@ -2882,4 +2882,6 @@ rx_memory_move_cost (enum machine_mode m
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 /* #include "gt-rx.h" */
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 166860)
+++ config/i386/i386.c	(working copy)
@@ -34703,5 +34703,7 @@ #define TARGET_VECTORIZE_AUTOVECTORIZE_V
 #define TARGET_ASM_CODE_END ix86_code_end
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 #include "gt-i386.h"
Index: config/sh/sh.c
===================================================================
--- config/sh/sh.c	(revision 166860)
+++ config/sh/sh.c	(working copy)
@@ -600,6 +600,8 @@ #define TARGET_BRANCH_TARGET_REGISTER_CA
 #define SYMBOL_FLAG_FUNCVEC_FUNCTION    (SYMBOL_FLAG_MACH_DEP << 0)
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Implement TARGET_HANDLE_OPTION.  */
 
Index: config/pdp11/pdp11.c
===================================================================
--- config/pdp11/pdp11.c	(revision 166860)
+++ config/pdp11/pdp11.c	(working copy)
@@ -1925,3 +1925,5 @@ pdp11_function_arg_advance (CUMULATIVE_A
 }
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
Index: config/microblaze/microblaze.c
===================================================================
--- config/microblaze/microblaze.c	(revision 166860)
+++ config/microblaze/microblaze.c	(working copy)
@@ -3052,5 +3052,7 @@ #define TARGET_ASM_FUNCTION_END_PROLOGUE
 #define TARGET_EXCEPT_UNWIND_INFO  sjlj_except_unwind_info
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 #include "gt-microblaze.h"
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 166860)
+++ config/avr/avr.c	(working copy)
@@ -219,6 +219,8 @@ static GTY(()) rtx zero_reg_rtx;
 #define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 static void
 avr_option_override (void)
Index: config/crx/crx.c
===================================================================
--- config/crx/crx.c	(revision 166860)
+++ config/crx/crx.c	(working copy)
@@ -207,6 +207,8 @@ static void crx_function_arg_advance (CU
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 
 /*****************************************************************************/
 /* TARGET HOOK IMPLEMENTATIONS						     */
Index: config/xtensa/xtensa.c
===================================================================
--- config/xtensa/xtensa.c	(revision 166860)
+++ config/xtensa/xtensa.c	(working copy)
@@ -277,6 +277,8 @@ static void xtensa_trampoline_init (rtx,
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 \f
 /* Functions to test Xtensa immediate operand validity.  */
 
Index: config/stormy16/stormy16.c
===================================================================
--- config/stormy16/stormy16.c	(revision 166860)
+++ config/stormy16/stormy16.c	(working copy)
@@ -2686,4 +2686,6 @@ xstormy16_return_in_memory (const_tree t
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #include "gt-stormy16.h"
Index: config/fr30/fr30.c
===================================================================
--- config/fr30/fr30.c	(revision 166860)
+++ config/fr30/fr30.c	(working copy)
@@ -206,6 +206,8 @@ #define MUST_SAVE_REGISTER(regno)      \
 #define TARGET_OPTION_OPTIMIZATION_TABLE fr30_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 
 /* Worker function for TARGET_CAN_ELIMINATE.  */
Index: config/lm32/lm32.c
===================================================================
--- config/lm32/lm32.c	(revision 166860)
+++ config/lm32/lm32.c	(working copy)
@@ -121,6 +121,8 @@ static void lm32_function_arg_advance (C
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 /* Current frame information calculated by lm32_compute_frame_size.  */
 static struct lm32_frame_info current_frame_info;
 
Index: config/moxie/moxie.c
===================================================================
--- config/moxie/moxie.c	(revision 166860)
+++ config/moxie/moxie.c	(working copy)
@@ -590,4 +590,6 @@ moxie_trampoline_init (rtx m_tramp, tree
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #include "gt-moxie.h"
Index: config/m68hc11/m68hc11.c
===================================================================
--- config/m68hc11/m68hc11.c	(revision 166860)
+++ config/m68hc11/m68hc11.c	(working copy)
@@ -312,6 +312,8 @@ enum reg_class m68hc11_tmp_regs_class = 
 #define TARGET_OPTION_OVERRIDE m68hc11_option_override
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 static void
 m68hc11_option_override (void)
Index: config/cris/cris.c
===================================================================
--- config/cris/cris.c	(revision 166860)
+++ config/cris/cris.c	(working copy)
@@ -250,6 +250,8 @@ static rtx cris_libcall_value (enum mach
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 /* Helper for cris_load_multiple_op and cris_ret_movem_op.  */
 
 bool
Index: config/iq2000/iq2000.c
===================================================================
--- config/iq2000/iq2000.c	(revision 166860)
+++ config/iq2000/iq2000.c	(working copy)
@@ -267,6 +267,8 @@ static bool iq2000_print_operand_punct_v
 #define TARGET_TRAMPOLINE_INIT		iq2000_trampoline_init
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Return nonzero if we split the address into high and low parts.  */
 
Index: config/mn10300/mn10300.c
===================================================================
--- config/mn10300/mn10300.c	(revision 166860)
+++ config/mn10300/mn10300.c	(working copy)
@@ -2513,3 +2513,5 @@ mn10300_adjust_sched_cost (rtx insn, rtx
 #define TARGET_SCHED_ADJUST_COST mn10300_adjust_sched_cost
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
Index: config/ia64/ia64.c
===================================================================
--- config/ia64/ia64.c	(revision 166860)
+++ config/ia64/ia64.c	(working copy)
@@ -633,6 +633,8 @@ #define TARGET_SCHED_FIRST_CYCLE_MULTIPA
 #define TARGET_PREFERRED_RELOAD_CLASS ia64_preferred_reload_class
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 typedef enum
   {
Index: config/m68k/m68k.c
===================================================================
--- config/m68k/m68k.c	(revision 166860)
+++ config/m68k/m68k.c	(working copy)
@@ -303,6 +303,8 @@ #define TARGET_SCHED_FIRST_CYCLE_MULTIPA
 };
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Base flags for 68k ISAs.  */
 #define FL_FOR_isa_00    FL_ISA_68000
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 166860)
+++ config/rs6000/rs6000.c	(working copy)
@@ -1703,6 +1703,8 @@ #define TARGET_DEFAULT_TARGET_FLAGS \
 #define TARGET_FUNCTION_VALUE rs6000_function_value
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Return number of consecutive hard regs needed starting at reg REGNO
    to hold something of mode MODE.
Index: config/picochip/picochip.c
===================================================================
--- config/picochip/picochip.c	(revision 166860)
+++ config/picochip/picochip.c	(working copy)
@@ -345,6 +345,8 @@ #define TARGET_SCHED_FIRST_CYCLE_MULTIPA
 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 
 /* Only return a value in memory if it is greater than 4 bytes.
Index: config/arc/arc.c
===================================================================
--- config/arc/arc.c	(revision 166860)
+++ config/arc/arc.c	(working copy)
@@ -172,6 +172,8 @@ static void arc_option_override (void);
 #define TARGET_TRAMPOLINE_INIT arc_trampoline_init
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Implement TARGET_HANDLE_OPTION.  */
 
Index: config/mcore/mcore.c
===================================================================
--- config/mcore/mcore.c	(revision 166860)
+++ config/mcore/mcore.c	(working copy)
@@ -261,6 +261,8 @@ static void       mcore_option_override	
 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Adjust the stack and return the number of bytes taken to do it.  */
 static void
Index: config/score/score.c
===================================================================
--- config/score/score.c	(revision 166860)
+++ config/score/score.c	(working copy)
@@ -1233,3 +1233,5 @@ score_block_move (rtx *ops)
 }
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
Index: config/arm/arm.c
===================================================================
--- config/arm/arm.c	(revision 166860)
+++ config/arm/arm.c	(working copy)
@@ -583,6 +583,8 @@ #define TARGET_VECTORIZE_SUPPORT_VECTOR_
   arm_builtin_support_vector_misalignment
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Obstack for minipool constant handling.  */
 static struct obstack minipool_obstack;
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 166860)
+++ config/pa/pa.c	(working copy)
@@ -388,6 +388,8 @@ static GTY((length ("n_deferred_plabels"
 #define TARGET_CAN_ELIMINATE pa_can_eliminate
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Parse the -mfixed-range= option string.  */
 
Index: config/mips/mips.c
===================================================================
--- config/mips/mips.c	(revision 166860)
+++ config/mips/mips.c	(working copy)
@@ -16625,5 +16625,7 @@ #define TARGET_DEFAULT_TARGET_FLAGS		\
 #define TARGET_SHIFT_TRUNCATION_MASK mips_shift_truncation_mask
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 #include "gt-mips.h"
Index: config/vax/vax.c
===================================================================
--- config/vax/vax.c	(revision 166860)
+++ config/vax/vax.c	(working copy)
@@ -125,6 +125,8 @@ static int vax_return_pops_args (tree, t
 #define TARGET_OPTION_OVERRIDE vax_option_override
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
 \f
 /* Set global variables as needed for the options enabled.  */
 
Index: config/h8300/h8300.c
===================================================================
--- config/h8300/h8300.c	(revision 166860)
+++ config/h8300/h8300.c	(working copy)
@@ -5964,3 +5964,5 @@ h8300_trampoline_init (rtx m_tramp, tree
 #define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
Index: config/v850/v850.c
===================================================================
--- config/v850/v850.c	(revision 166860)
+++ config/v850/v850.c	(working copy)
@@ -3207,4 +3207,6 @@ v850_issue_rate (void)
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 #include "gt-v850.h"
Index: config/mmix/mmix.c
===================================================================
--- config/mmix/mmix.c	(revision 166860)
+++ config/mmix/mmix.c	(working copy)
@@ -265,6 +265,8 @@ static void mmix_trampoline_init (rtx, t
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
+
 /* Functions that are expansions for target macros.
    See Target Macros in `Using and Porting GCC'.  */
 
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 166860)
+++ config/bfin/bfin.c	(working copy)
@@ -6697,3 +6697,5 @@ bfin_expand_builtin (tree exp, rtx targe
 #define TARGET_TRAMPOLINE_INIT bfin_trampoline_init
 
 struct gcc_target targetm = TARGET_INITIALIZER;
+
+struct gcc_target_internal target_internalm = TARGET_INTERNAL_INITIALIZER;
0a1,65
> /* Data structure definitions for a generic GCC target.
>    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
> 
>    This program is free software; you can redistribute it and/or modify it
>    under the terms of the GNU General Public License as published by the
>    Free Software Foundation; either version 3, or (at your option) any
>    later version.
> 
>    This program is distributed in the hope that it will be useful,
>    but WITHOUT ANY WARRANTY; without even the implied warranty of
>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>    GNU General Public License for more details.
> 
>    You should have received a copy of the GNU General Public License
>    along with this program; see the file COPYING3.  If not see
>    <http://www.gnu.org/licenses/>.
> 
>    In other words, you are welcome to use, share and improve this program.
>    You are forbidden to forbid anyone else to use, share and improve
>    what you give them.   Help stamp out software-hoarding!  */
> 
> 
> /* This file contains a data structure that describes a GCC target.
>    At present it is incomplete, but in future it should grow to
>    contain most or all target machine and target O/S specific
>    information.
> 
>    This structure has its initializer declared in target-def.h in the
>    form of large macro TARGET_INITIALIZER that expands to many smaller
>    macros.
> 
>    The smaller macros each initialize one component of the structure,
>    and each has a default.  Each target should have a file that
>    includes target.h and target-def.h, and overrides any inappropriate
>    defaults by undefining the relevant macro and defining a suitable
>    replacement.  That file should then contain the definition of
>    "targetm" like so:
> 
>    struct gcc_target targetm = TARGET_INITIALIZER;
> 
>    Doing things this way allows us to bring together everything that
>    defines a GCC target.  By supplying a default that is appropriate
>    to most targets, we can easily add new items without needing to
>    edit dozens of target configuration files.  It should also allow us
>    to gradually reduce the amount of conditional compilation that is
>    scattered throughout GCC.  */
> 
> #ifndef GCC_TARGET_INTERNAL_H
> #define GCC_TARGET_INTERNAL_H
> 
> #include "tm.h"
> #include "insn-modes.h"
> 
> /* The target structure.  This holds all the backend hooks.  */
> #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
> #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
> #define DEFHOOK_UNDOC DEFHOOK
> #define HOOKSTRUCT(FRAGMENT) FRAGMENT
> 
> #include "target-internal.def"
> 
> extern struct gcc_target_internal target_internalm;
> 
> #endif /* GCC_TARGET_INTERNALH */
0a1,145
> /* Target hook definitions.
>    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
> 
>    This program is free software; you can redistribute it and/or modify it
>    under the terms of the GNU General Public License as published by the
>    Free Software Foundation; either version 3, or (at your option) any
>    later version.
> 
>    This program is distributed in the hope that it will be useful,
>    but WITHOUT ANY WARRANTY; without even the implied warranty of
>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>    GNU General Public License for more details.
> 
>    You should have received a copy of the GNU General Public License
>    along with this program; see the file COPYING3.  If not see
>    <http://www.gnu.org/licenses/>.
> 
>    In other words, you are welcome to use, share and improve this program.
>    You are forbidden to forbid anyone else to use, share and improve
>    what you give them.   Help stamp out software-hoarding!  */
> 
> /* The following macros should be provided by the including file:
> 
>    DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT): Define a function-valued hook.
>    DEFHOOKPOD(DOC, TYPE, NAME, INIT): Define a piece-of-data 'hook'.  */
> 
> /* Defaults for optional macros:
>    DEFHOOKPODX(NAME, TYPE, INIT): Like DEFHOOKPOD, but share documentation
>    with the previous 'hook'.  */
> #ifndef DEFHOOKPODX
> #define DEFHOOKPODX(NAME, TYPE, INIT) DEFHOOKPOD (NAME, 0, TYPE, INIT)
> #endif
>    
> /* HOOKSTRUCT(FRAGMENT): Declarator fragments to encapsulate all the
>    members into a struct gcc_target, which in turn contains several
>    sub-structs.  */
> #ifndef HOOKSTRUCT
> #define HOOKSTRUCT(FRAGMENT)
> #endif
> /* HOOK_VECTOR: Start a struct declaration, which then gets its own initializer.
>    HOOK_VECTOR_END: Close a struct declaration, providing a member declarator
>                     name for nested use.  */
> #ifndef HOOK_VECTOR_1
> #define HOOK_VECTOR_1(NAME, FRAGMENT) HOOKSTRUCT(FRAGMENT)
> #endif
> #define HOOK_VECTOR(INIT_NAME, SNAME) HOOK_VECTOR_1 (INIT_NAME, struct SNAME {)
> #define HOOK_VECTOR_END(DECL_NAME) HOOK_VECTOR_1(,} DECL_NAME ;)
> 
> HOOK_VECTOR (TARGET_INTERNAL_INITIALIZER, gcc_target_internal)
> 
> /* See target.def for an explanation of the fields.  */
> 
> #undef HOOK_PREFIX
> #define HOOK_PREFIX "TARGET_"
> 
> /* Return true if a parameter must be passed by reference.  TYPE may
>    be null if this is a libcall.  CA may be null if this query is
>    from __builtin_va_arg.  */
> DEFHOOK
> (pass_by_reference,
>  "",
>  bool,
>  (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
>  hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
> 
> /* Returns pretend_argument_size.  */
> DEFHOOK
> (setup_incoming_varargs,
>  "",
>  void, (CUMULATIVE_ARGS *args_so_far, enum machine_mode mode, tree type,
> 	int *pretend_args_size, int second_time),
>  default_setup_incoming_varargs)
> 
> DEFHOOK
> (strict_argument_naming,
>  "",
>  bool, (CUMULATIVE_ARGS *ca),
>  hook_bool_CUMULATIVE_ARGS_false)
> 
> /* Returns true if we should use
>    targetm.calls.setup_incoming_varargs() and/or
>    targetm.calls.strict_argument_naming().  */
> DEFHOOK
> (pretend_outgoing_varargs_named,
>  "",
>  bool, (CUMULATIVE_ARGS *ca),
>  default_pretend_outgoing_varargs_named)
> 
> /* Return true if type TYPE, mode MODE, which is passed by reference,
>    should have the object copy generated by the callee rather than
>    the caller.  It is never called for TYPE requiring constructors.  */
> DEFHOOK
> (callee_copies,
>  "",
>  bool,
>  (CUMULATIVE_ARGS *cum, enum machine_mode mode, const_tree type, bool named),
>  hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false)
> 
> /* Return zero for arguments passed entirely on the stack or entirely
>    in registers.  If passed in both, return the number of bytes passed
>    in registers; the balance is therefore passed on the stack.  */
> DEFHOOK
> (arg_partial_bytes,
>  "",
>  int, (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, bool named),
>  hook_int_CUMULATIVE_ARGS_mode_tree_bool_0)
> 
> /* Update the state in CA to advance past an argument in the
>    argument list.  The values MODE, TYPE, and NAMED describe that
>    argument.  */
> /* ??? tm.texi still only describes the old macro.  */
> DEFHOOK_UNDOC
> (function_arg_advance,
>  "",
>  void,
>  (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type, bool named),
>  default_function_arg_advance)
> 
> /* Return zero if the argument described by the state of CA should
>    be placed on a stack, or a hard register in which to store the
>    argument.  The values MODE, TYPE, and NAMED describe that
>    argument.  */
> /* ??? tm.texi still only describes the old macro.  */
> DEFHOOK_UNDOC
> (function_arg,
>  "",
>  rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
>        bool named),
>  default_function_arg)
> 
> /* Likewise, but for machines with register windows.  Return the
>    location where the argument will appear to the callee.  */
> /* ??? tm.texi still only describes the old macro.  */
> DEFHOOK_UNDOC
> (function_incoming_arg,
>  "",
>  rtx, (CUMULATIVE_ARGS *ca, enum machine_mode mode, const_tree type,
>        bool named),
>  default_function_incoming_arg)
> 
> /* Empty macro arguments are undefined in C90, so use an empty macro.  */
> #define C90_EMPTY_HACK
> /* Close the 'struct gcc_target_internal' definition.  */
> HOOK_VECTOR_END (C90_EMPTY_HACK)

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17 14:34                         ` Joern Rennecke
  2010-11-17 16:01                           ` P.S.: Re: CUMULATIVE_ARGS in hooks Joern Rennecke
@ 2010-11-17 19:20                           ` Nathan Froyd
  2010-11-17 19:31                             ` Joern Rennecke
  1 sibling, 1 reply; 24+ messages in thread
From: Nathan Froyd @ 2010-11-17 19:20 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: Paolo Bonzini, Ian Lance Taylor, gcc

On Tue, Nov 16, 2010 at 10:22:00PM -0500, Joern Rennecke wrote:
> Quoting Nathan Froyd <froydnj@codesourcery.com>:
> >I am admittedly a C++ newbie; the first thing I thought of was:
> >
> >class gcc::cumulative_args {
> >  virtual void advance (...) = 0;
> >  virtual rtx arg (...) = 0;
> >  virtual rtx incoming_arg (...) { return this->arg (...); };
> >  virtual int arg_partial_bytes (...) = 0;
> >  // ...and so on for many of the hooks that take CUMULATIVE_ARGS *
> >  // possibly with default implementations instead of pure virtual
> >  // functions.
> >};
> 
> Trying to put a target-derived object of that into struct rtl_data would
> be nonsentical.  You might store a pointer, of course.

Yes, of course.  I thought that might have been clear from context.

> Does that mean you acknowledge that we shouldn't have CUMULATIVE_ARGS
> taking hooks in the global target vector?

Maybe?  I think the methods discussed in this thread would be better for
when we do move to C++.  I don't think your original proposal or
anything that sacrifices the type-safety of the current interface is the
way forward.

-Nathan

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization)
  2010-11-17 19:20                           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Nathan Froyd
@ 2010-11-17 19:31                             ` Joern Rennecke
  0 siblings, 0 replies; 24+ messages in thread
From: Joern Rennecke @ 2010-11-17 19:31 UTC (permalink / raw)
  To: Nathan Froyd; +Cc: Paolo Bonzini, Ian Lance Taylor, gcc

Quoting Nathan Froyd <froydnj@codesourcery.com>:

> On Tue, Nov 16, 2010 at 10:22:00PM -0500, Joern Rennecke wrote:
...
>> Does that mean you acknowledge that we shouldn't have CUMULATIVE_ARGS
>> taking hooks in the global target vector?
>
> Maybe?  I think the methods discussed in this thread would be better for
> when we do move to C++.  I don't think your original proposal or
> anything that sacrifices the type-safety of the current interface is the
> way forward.

You can find my original proposal fleshed out here:
http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01769.html

I have also made an alternate proposal that keeps type safety, and regains
dependency sanity by moving the CUMULATIVE_ARGS taking hooks out of targetm:
http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01810.html

This is conceptually closer to the C++ proposals; the new target_internalm
hook vector serves a similar purpose as a vtable for a cumulative_arg
class object.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2010-11-17 15:45 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-15 11:17 RFC: semi-automatic hookization Joern Rennecke
2010-11-15 16:33 ` Joseph S. Myers
2010-11-15 17:45   ` Joern Rennecke
2010-11-15 18:59     ` Joseph S. Myers
2010-11-16 10:12       ` Joern Rennecke
2010-11-16 15:43         ` Ian Lance Taylor
2010-11-16 16:14           ` Nathan Froyd
2010-11-16 17:34           ` Joern Rennecke
2010-11-16 22:53           ` Joern Rennecke
2010-11-17  0:36           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Joern Rennecke
2010-11-17  2:04             ` Ian Lance Taylor
2010-11-17  3:04               ` Paolo Bonzini
2010-11-17  3:22                 ` Joern Rennecke
2010-11-17  3:45                   ` Ian Lance Taylor
2010-11-17  4:06                     ` Paolo Bonzini
2010-11-17 11:58                       ` Nathan Froyd
2010-11-17 14:34                         ` Joern Rennecke
2010-11-17 16:01                           ` P.S.: Re: CUMULATIVE_ARGS in hooks Joern Rennecke
2010-11-17 19:20                           ` CUMULATIVE_ARGS in hooks (Was: RFC: semi-automatic hookization) Nathan Froyd
2010-11-17 19:31                             ` Joern Rennecke
2010-11-17 15:25                         ` Ian Lance Taylor
2010-11-17 15:45                           ` Joern Rennecke
2010-11-15 22:08   ` RFC: semi-automatic hookization Paolo Bonzini
2010-11-15 22:16     ` Joern Rennecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).