public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Can we speed up the gcc_target structure?
@ 2004-01-19 23:42 Richard Kenner
  2004-01-19 23:46 ` Zack Weinberg
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Kenner @ 2004-01-19 23:42 UTC (permalink / raw)
  To: zack; +Cc: gcc

    Whether by accident or intention you picked a lot of stuff having to
    do with register classes, 

Accident: I was going sequentially through alpha.h.

    Wasn't Michael Matz just saying that regclass.c needed a major rework
    anyway, or the new register allocator would never be able to replace
    the old?  I don't know what his design looks like, or even if he has
    one yet, but surely there is a simpler way to structure this, that
    doesn't involve lots of little tiny macros.

I don't see what that has to do with the specification of classes, which
are attributes of the machine.  Those macros are used by far more than
just regclass.c and the register allocator ...

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 23:42 Can we speed up the gcc_target structure? Richard Kenner
@ 2004-01-19 23:46 ` Zack Weinberg
  0 siblings, 0 replies; 45+ messages in thread
From: Zack Weinberg @ 2004-01-19 23:46 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

>     Wasn't Michael Matz just saying that regclass.c needed a major rework
>     anyway, or the new register allocator would never be able to replace
>     the old?  I don't know what his design looks like, or even if he has
>     one yet, but surely there is a simpler way to structure this, that
>     doesn't involve lots of little tiny macros.
>
> I don't see what that has to do with the specification of classes, which
> are attributes of the machine.  Those macros are used by far more than
> just regclass.c and the register allocator ...

I'm speculating that a simpler specification of classes could be
informed by the needs of the new register allocator.  That's all.

zw

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

* Re: Can we speed up the gcc_target structure?
@ 2004-01-19 23:48 Richard Kenner
  0 siblings, 0 replies; 45+ messages in thread
From: Richard Kenner @ 2004-01-19 23:48 UTC (permalink / raw)
  To: zack; +Cc: gcc

    I'm speculating that a simpler specification of classes could be
    informed by the needs of the new register allocator.  That's all.

I don't see it.  The complexity of register class specifications is
dictated by the complexity of architectures, not anything we put into GCC:
it has to be expressive enough to describe all architectures.

Sure, it's somewhat redundant, in that we have maps both ways, and a few
macros could be eliminated in that process, but it doesn't seem worth the
effort to me.

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 21:25 Richard Kenner
@ 2004-01-19 23:36 ` Zack Weinberg
  0 siblings, 0 replies; 45+ messages in thread
From: Zack Weinberg @ 2004-01-19 23:36 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

> #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)  \
>   if (GET_MODE_CLASS (MODE) == MODE_INT		\
>       && GET_MODE_SIZE (MODE) < UNITS_PER_WORD)	\
>     {						\
>       if ((MODE) == SImode)			\
> 	(UNSIGNEDP) = 0;			\
>       (MODE) = DImode;				\
>     }
> #define HARD_REGNO_NREGS(REGNO, MODE)   \
>   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
> #define HARD_REGNO_MODE_OK(REGNO, MODE) 				\
>   ((REGNO) >= 32 && (REGNO) <= 62 					\
>    ? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode		\
>    : 1)
> #define VECTOR_MODE_SUPPORTED_P(MODE) \
>   (TARGET_MAX \
>    && ((MODE) == V8QImode || (MODE) == V4HImode || (MODE) == V2SImode))
> #define MODES_TIEABLE_P(MODE1, MODE2) 				\
>   (HARD_REGNO_MODE_OK (32, (MODE1))				\
>    ? HARD_REGNO_MODE_OK (32, (MODE2))				\
>    : 1)
> #define SECONDARY_MEMORY_NEEDED_MODE(MODE)		\
>   (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE)		\
>    : GET_MODE_SIZE (MODE) >= 4 ? (MODE)			\
>    : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0))
> #define CLASS_MAX_NREGS(CLASS, MODE)				\
>  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
> #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		\
>   (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)			\
>    ? reg_classes_intersect_p (FLOAT_REGS, CLASS) : 0)
> #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)	\
>   (((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS)	\
>    ? 2							\
>    : TARGET_FIX ? 3 : 4+2*alpha_memory_latency)
> #define MEMORY_MOVE_COST(MODE,CLASS,IN)  (2*alpha_memory_latency)
...

Whether by accident or intention you picked a lot of stuff having to
do with register classes, and I'm going to turn around and say that
this is a place ripe for redesign.  Wasn't Michael Matz just saying
that regclass.c needed a major rework anyway, or the new register
allocator would never be able to replace the old?  I don't know what
his design looks like, or even if he has one yet, but surely there is
a simpler way to structure this, that doesn't involve lots of little
tiny macros.

zw

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

* Re: Can we speed up the gcc_target structure?
@ 2004-01-19 21:25 Richard Kenner
  2004-01-19 23:36 ` Zack Weinberg
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Kenner @ 2004-01-19 21:25 UTC (permalink / raw)
  To: zack; +Cc: gcc

    > True for some, but not others.  Yes, we have a lot of macros which are
    > actually functions, but we also have a lot of macros that are just a
    > half dozen tokens which would have to be converted into a function.

    Do you have any in particular in mind?

If the idea is to eventually convert *all* target macros, then most are
in that category (though "half dozen" should probabaly have been "few dozen").

From alpha.h:

#define WORD_SWITCH_TAKES_ARG(STR)		\
 (!strcmp (STR, "rpath") || DEFAULT_WORD_SWITCH_TAKES_ARG(STR))
#define TARGET_FLOAT_FORMAT \
  (TARGET_FLOAT_VAX ? VAX_FLOAT_FORMAT : IEEE_FLOAT_FORMAT)
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE)  \
  if (GET_MODE_CLASS (MODE) == MODE_INT		\
      && GET_MODE_SIZE (MODE) < UNITS_PER_WORD)	\
    {						\
      if ((MODE) == SImode)			\
	(UNSIGNEDP) = 0;			\
      (MODE) = DImode;				\
    }
#define HARD_REGNO_NREGS(REGNO, MODE)   \
  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define HARD_REGNO_MODE_OK(REGNO, MODE) 				\
  ((REGNO) >= 32 && (REGNO) <= 62 					\
   ? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode		\
   : 1)
#define VECTOR_MODE_SUPPORTED_P(MODE) \
  (TARGET_MAX \
   && ((MODE) == V8QImode || (MODE) == V4HImode || (MODE) == V2SImode))
#define MODES_TIEABLE_P(MODE1, MODE2) 				\
  (HARD_REGNO_MODE_OK (32, (MODE1))				\
   ? HARD_REGNO_MODE_OK (32, (MODE2))				\
   : 1)
#define SECONDARY_MEMORY_NEEDED_MODE(MODE)		\
  (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE)		\
   : GET_MODE_SIZE (MODE) >= 4 ? (MODE)			\
   : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0))
#define CLASS_MAX_NREGS(CLASS, MODE)				\
 ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS)		\
  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO)			\
   ? reg_classes_intersect_p (FLOAT_REGS, CLASS) : 0)
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2)	\
  (((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS)	\
   ? 2							\
   : TARGET_FIX ? 3 : 4+2*alpha_memory_latency)
#define MEMORY_MOVE_COST(MODE,CLASS,IN)  (2*alpha_memory_latency)
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
  ((OFFSET) = alpha_initial_elimination_offset(FROM, TO))
#define FUNCTION_VALUE_REGNO_P(N)  \
  ((N) == 0 || (N) == 1 || (N) == 32 || (N) == 33)
#define FUNCTION_ARG_REGNO_P(N) \
  (((N) >= 16 && (N) <= 21) || ((N) >= 16 + 32 && (N) <= 21 + 32))
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT)  (CUM) = 0
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
  ((MODE) == TFmode || (MODE) == TCmode)


... and so on ...

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 19:05 Richard Kenner
@ 2004-01-19 21:15 ` Zack Weinberg
  0 siblings, 0 replies; 45+ messages in thread
From: Zack Weinberg @ 2004-01-19 21:15 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

>     If done right, it ought to be simpler than target macros.  If you look
>     at individual target macros in isolation, conversion from macro to
>     hook invariably makes the back-end interface simpler, just because it
>     forces you not to do the horrible define-here-redefine-there mess that
>     is the current state of a lot of the macros.  
>
> True for some, but not others.  Yes, we have a lot of macros which are actually
> functions, but we also have a lot of macros that are just a half dozen
> tokens which would have to be converted into a function.

Do you have any in particular in mind?

zw

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 19:33           ` DJ Delorie
@ 2004-01-19 20:41             ` Richard Henderson
  0 siblings, 0 replies; 45+ messages in thread
From: Richard Henderson @ 2004-01-19 20:41 UTC (permalink / raw)
  To: DJ Delorie; +Cc: ian, gcc

On Mon, Jan 19, 2004 at 02:32:19PM -0500, DJ Delorie wrote:
> Maybe I'm misremembering, but wasn't one of the goals of using the
> target structure to be able to switch them at runtime?

It was mentioned, but I never took it that seriously.


r~

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 12:01 ` Richard Guenther
@ 2004-01-19 20:02   ` Richard Henderson
  0 siblings, 0 replies; 45+ messages in thread
From: Richard Henderson @ 2004-01-19 20:02 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Richard Kenner, ian, gcc

On Mon, Jan 19, 2004 at 01:01:54PM +0100, Richard Guenther wrote:
> A better way would be to handle those target functions that can be const
> with a hybrid approach like
> 
> #define TARGET_FUNCTION_FOO_CONST_VALUE false
> 
> static inline bool target_function_foo(...)
> {
> #ifdef TARGET_FUNCTION_FOO_CONST_VALUE
>    return TARGET_FUNCTION_FOO_CONST_VALUE;
> #else
>    return vec->target_function_foo(...);
> #endif
> }

If we were going to do something like this, we shouldn't bother
with the vector, we should just make the calls direct.  There's
a not insignificant cost to indirect vs direct calls.


r~

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:37         ` Richard Henderson
@ 2004-01-19 19:33           ` DJ Delorie
  2004-01-19 20:41             ` Richard Henderson
  0 siblings, 1 reply; 45+ messages in thread
From: DJ Delorie @ 2004-01-19 19:33 UTC (permalink / raw)
  To: rth; +Cc: ian, gcc


> > What is preventing us from declaring the structure as constant so we
> > should get propagation even with current design?
> 
> Targets that modify the structure at startup.

Maybe I'm misremembering, but wasn't one of the goals of using the
target structure to be able to switch them at runtime?  If so, a
command line argument could change the pointer to point to a different
structure, which completely invalidates all such optimizations.

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

* Re: Can we speed up the gcc_target structure?
@ 2004-01-19 19:05 Richard Kenner
  2004-01-19 21:15 ` Zack Weinberg
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Kenner @ 2004-01-19 19:05 UTC (permalink / raw)
  To: zack; +Cc: gcc

    If done right, it ought to be simpler than target macros.  If you look
    at individual target macros in isolation, conversion from macro to
    hook invariably makes the back-end interface simpler, just because it
    forces you not to do the horrible define-here-redefine-there mess that
    is the current state of a lot of the macros.  

True for some, but not others.  Yes, we have a lot of macros which are actually
functions, but we also have a lot of macros that are just a half dozen
tokens which would have to be converted into a function.

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 18:18 Richard Kenner
@ 2004-01-19 18:26 ` Zack Weinberg
  0 siblings, 0 replies; 45+ messages in thread
From: Zack Weinberg @ 2004-01-19 18:26 UTC (permalink / raw)
  To: Richard Kenner; +Cc: gcc

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

>     Does your opinion change if the target parameters are properly
>     redesigned, as I suggested in another message to this thread?
>
> Somewhat, but I still wonder whether the complexity of such a scheme
> is worth the ability to have common .o files.

If done right, it ought to be simpler than target macros.  If you look
at individual target macros in isolation, conversion from macro to
hook invariably makes the back-end interface simpler, just because it
forces you not to do the horrible define-here-redefine-there mess that
is the current state of a lot of the macros.  So I think doing it
right will be natural, except where actual design effort is required,
such as for the calling-convention macros.  And there the design
effort is worth it in its own terms.

zw

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

* Re: Can we speed up the gcc_target structure?
@ 2004-01-19 18:18 Richard Kenner
  2004-01-19 18:26 ` Zack Weinberg
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Kenner @ 2004-01-19 18:18 UTC (permalink / raw)
  To: zack; +Cc: gcc

    Does your opinion change if the target parameters are properly
    redesigned, as I suggested in another message to this thread?

Somewhat, but I still wonder whether the complexity of such a scheme
is worth the ability to have common .o files.

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 11:51 Richard Kenner
  2004-01-19 12:01 ` Richard Guenther
  2004-01-19 14:16 ` Robert Dewar
@ 2004-01-19 18:03 ` Zack Weinberg
  2 siblings, 0 replies; 45+ messages in thread
From: Zack Weinberg @ 2004-01-19 18:03 UTC (permalink / raw)
  To: Richard Kenner; +Cc: ian, gcc

kenner@vlsi1.ultra.nyu.edu (Richard Kenner) writes:

> I have to say that I was never happy with the move to the target structure,
> but couldn't completely put my finger on why.
>
> One reason I didn't like it was a feeling that it made references to these
> parameters lexically more complex and hence made the code harder to read, but
> that's not a strong reason.
>
> Howver, *this* is the reason I was trying to express: a significant fraction
> of these parameters are constants on most targets and we lose that with a
> move to the target structure.

Does your opinion change if the target parameters are properly
redesigned, as I suggested in another message to this thread?

zw

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

* Re: Can we speed up the gcc_target structure?
  2004-01-19 11:51 Richard Kenner
  2004-01-19 12:01 ` Richard Guenther
@ 2004-01-19 14:16 ` Robert Dewar
  2004-01-19 18:03 ` Zack Weinberg
  2 siblings, 0 replies; 45+ messages in thread
From: Robert Dewar @ 2004-01-19 14:16 UTC (permalink / raw)
  To: Richard Kenner; +Cc: ian, gcc

Richard Kenner wrote:

> My sense would be to revert these changes and eliminate the target stucture
> in favor of the simpler macro approach.

Well certainly it would be useful to have precise measurements of the
impact. Closer to home (if home is GNAT) debug.ads/adb do not make the
debug flags constant in GNAT, so that they can be changed with -gnatd?
and as far as I know we never measured the impact of this similar kind
of issue -- we should :-)

Certain of the GNAT -gnatd switches are user important (like -gnatdO 
probably), but most are not.


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

* Re: Can we speed up the gcc_target structure?
  2004-01-19  1:12 ` Geoff Keating
@ 2004-01-19 13:51   ` Ian Lance Taylor
  0 siblings, 0 replies; 45+ messages in thread
From: Ian Lance Taylor @ 2004-01-19 13:51 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc

Geoff Keating <geoffk@geoffk.org> writes:

> Ian Lance Taylor <ian@wasabisystems.com> writes:
> 
> ...
> > Any thoughts?  Does anybody think this would be a waste of time?  Does
> > anybody have a better approach to solving the general problem?
> 
> What happens if you compile with --enable-intermodule?

targetm is not a const structure, so I can't see gcc knowing that some
of the fields in fact do not change.  But I haven't actually tried it.

Ian

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

* Re:  Can we speed up the gcc_target structure?
  2004-01-19 11:51 Richard Kenner
@ 2004-01-19 12:01 ` Richard Guenther
  2004-01-19 20:02   ` Richard Henderson
  2004-01-19 14:16 ` Robert Dewar
  2004-01-19 18:03 ` Zack Weinberg
  2 siblings, 1 reply; 45+ messages in thread
From: Richard Guenther @ 2004-01-19 12:01 UTC (permalink / raw)
  To: Richard Kenner; +Cc: ian, gcc

On Mon, 19 Jan 2004, Richard Kenner wrote:

> My sense would be to revert these changes and eliminate the target stucture
> in favor of the simpler macro approach.
>
> Am I the only one who feels this way?  If not, this may be an issue for the
> SC to address.

A better way would be to handle those target functions that can be const
with a hybrid approach like

#define TARGET_FUNCTION_FOO_CONST_VALUE false

static inline bool target_function_foo(...)
{
#ifdef TARGET_FUNCTION_FOO_CONST_VALUE
   return TARGET_FUNCTION_FOO_CONST_VALUE;
#else
   return vec->target_function_foo(...);
#endif
}

and for sanity

struct target_vector {
  ...
#ifndef TARGET_FUNCTION_FOO_CONST_VALUE
  bool (*target_function_foo)(...);
#endif
  ...
};

or semantically similar approach.  This way targets can decide, if they
want a modifiable target vector, or if they have a more complex
requirement.

Richard.

--
Richard Guenther <richard dot guenther at uni-tuebingen dot de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/

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

* Re:  Can we speed up the gcc_target structure?
@ 2004-01-19 11:51 Richard Kenner
  2004-01-19 12:01 ` Richard Guenther
                   ` (2 more replies)
  0 siblings, 3 replies; 45+ messages in thread
From: Richard Kenner @ 2004-01-19 11:51 UTC (permalink / raw)
  To: ian; +Cc: gcc

I have to say that I was never happy with the move to the target structure,
but couldn't completely put my finger on why.

One reason I didn't like it was a feeling that it made references to these
parameters lexically more complex and hence made the code harder to read, but
that's not a strong reason.

Howver, *this* is the reason I was trying to express: a significant fraction
of these parameters are constants on most targets and we lose that with a
move to the target structure.

I've seen the argument that it would be good to be able to have the binaries
for many of the compiler files be target-independent, but I don't see that as
a major argument given compilation speeds at the moment.  I think the loss in
compile-time performance is significant.

My sense would be to revert these changes and eliminate the target stucture
in favor of the simpler macro approach.

Am I the only one who feels this way?  If not, this may be an issue for the
SC to address.

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 23:27         ` Jan Hubicka
  2004-01-18 23:34           ` Jakub Jelinek
@ 2004-01-19  1:36           ` Chris Lattner
  1 sibling, 0 replies; 45+ messages in thread
From: Chris Lattner @ 2004-01-19  1:36 UTC (permalink / raw)
  To: Jan Hubicka
  Cc: Jan Hubicka, Richard Henderson, Kaveh R. Ghazi, ian, gcc,
	Joseph S. Myers

On Mon, 19 Jan 2004, Jan Hubicka wrote:
> > Ok, great.  :)
>
> Thus my concerns were mostly about whether it is good idea to add
> feature reading external list in addition to the attribute.
> If it is common that the external list is available by some means that
> can't easilly provide the attribute, just let me know.

I don't think there is any existing attribute, but one could easily be
added.  Linker scripts are the only extant mechanism that I know of to
handle things like this.

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:25     ` Zack Weinberg
  2004-01-19  0:53       ` Ian Lance Taylor
@ 2004-01-19  1:18       ` Geoff Keating
  1 sibling, 0 replies; 45+ messages in thread
From: Geoff Keating @ 2004-01-19  1:18 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc

"Zack Weinberg" <zack@codesourcery.com> writes:

> Of course inefficiencies are going to be introduced if we just convert
> each macro to a target hook with the same semantics.  But that isn't
> the only option on the table.  The right thing is to redesign this
> interface so that it doesn't *need* 100+ macros and toggles.  If this
> is done properly, then not only should there be no inefficiency
> introduced by going through the target vector, but also we would have
> something that was straightforward to maintain and straightforward to
> add support for new architectures.

I agree with this paragraph.  Our function-call ABI description is
very suboptimal, and performance is the least of the problems; I think
there are still targets where no-one can describe the ABI without
making reference to function.c.

-- 
- Geoffrey Keating <geoffk@geoffk.org>

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18  8:37 Ian Lance Taylor
                   ` (2 preceding siblings ...)
  2004-01-18 13:58 ` Kaveh R. Ghazi
@ 2004-01-19  1:12 ` Geoff Keating
  2004-01-19 13:51   ` Ian Lance Taylor
  3 siblings, 1 reply; 45+ messages in thread
From: Geoff Keating @ 2004-01-19  1:12 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Ian Lance Taylor <ian@wasabisystems.com> writes:

...
> Any thoughts?  Does anybody think this would be a waste of time?  Does
> anybody have a better approach to solving the general problem?

What happens if you compile with --enable-intermodule?

-- 
- Geoffrey Keating <geoffk@geoffk.org>

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:25     ` Zack Weinberg
@ 2004-01-19  0:53       ` Ian Lance Taylor
  2004-01-19  1:18       ` Geoff Keating
  1 sibling, 0 replies; 45+ messages in thread
From: Ian Lance Taylor @ 2004-01-19  0:53 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc

"Zack Weinberg" <zack@codesourcery.com> writes:

> Of course inefficiencies are going to be introduced if we just convert
> each macro to a target hook with the same semantics.  But that isn't
> the only option on the table.  The right thing is to redesign this
> interface so that it doesn't *need* 100+ macros and toggles.  If this
> is done properly, then not only should there be no inefficiency
> introduced by going through the target vector, but also we would have
> something that was straightforward to maintain and straightforward to
> add support for new architectures.
> 
> As a data point, I am aware of another (proprietary) compiler that
> completely isolates the back end from the optimizers, to the point
> where the back end module can be swapped out at runtime, and it
> benchmarks competitively or faster than GCC on similar input.  So I
> don't believe that this is impossible.

Sounds good.  I think most people would agree that gcc has always
brought details of the target too far forward in the compilation
process.  But it's a pretty substantial project, given the current
code base.

Ian

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 23:27         ` Jan Hubicka
@ 2004-01-18 23:34           ` Jakub Jelinek
  2004-01-19  1:36           ` Chris Lattner
  1 sibling, 0 replies; 45+ messages in thread
From: Jakub Jelinek @ 2004-01-18 23:34 UTC (permalink / raw)
  To: Jan Hubicka
  Cc: Chris Lattner, Jan Hubicka, Richard Henderson, Kaveh R. Ghazi,
	ian, gcc, Joseph S. Myers

On Mon, Jan 19, 2004 at 12:27:01AM +0100, Jan Hubicka wrote:
> I think that at least glibc has special marker for each external symbol
> so it is not concern there.

No.  glibc has some markers for internal symbols which are not static
(__attribute__((visibility ("hidden"))) ).
But in the end what is really exported is controlled by the linker version
script.

	Jakub

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:50       ` Chris Lattner
@ 2004-01-18 23:27         ` Jan Hubicka
  2004-01-18 23:34           ` Jakub Jelinek
  2004-01-19  1:36           ` Chris Lattner
  0 siblings, 2 replies; 45+ messages in thread
From: Jan Hubicka @ 2004-01-18 23:27 UTC (permalink / raw)
  To: Chris Lattner
  Cc: Jan Hubicka, Jan Hubicka, Richard Henderson, Kaveh R. Ghazi, ian,
	gcc, Joseph S. Myers

> On Sun, 18 Jan 2004, Jan Hubicka wrote:
> > If you mark no symbols via special attribute, only main should be
> > external.  If you mark more, you get more.
> 
> Ok, I see.
> 
> > > > I suppose this is mostly equivalent to what LLVM have except for the
> > > > fact that list of symbols with external linkage is boundled in the
> > > > source itself, instead of being in separate file. Do you have any
> > > > experience with the separate file having considerable benefits?
> > >
> > > I'm not sure if I understand what you mean here, can you please clarify?
> >
> > You mentioned that instead of using attribute in the source file, you
> > get list of functions.  From here the lists are comming?
> 
> We use an external file (a linker script basically) to decide the list.
> You can also specify the list with a -Wl option.
> 
> > > (for example) dynamically load shared objects that call back into the main
> > > program.  People will get unhappy if 'gimp' doesn't work in this mode, for
> > > example.
> >
> > I expect people to just mark the interface functions via the attribute.
> 
> Ok, great.  :)

Thus my concerns were mostly about whether it is good idea to add
feature reading external list in addition to the attribute.
If it is common that the external list is available by some means that
can't easilly provide the attribute, just let me know.

I think that at least glibc has special marker for each external symbol
so it is not concern there.

Honza
> 
> -Chris
> 
> -- 
> http://llvm.cs.uiuc.edu/
> http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:48     ` Jan Hubicka
@ 2004-01-18 22:50       ` Chris Lattner
  2004-01-18 23:27         ` Jan Hubicka
  0 siblings, 1 reply; 45+ messages in thread
From: Chris Lattner @ 2004-01-18 22:50 UTC (permalink / raw)
  To: Jan Hubicka
  Cc: Jan Hubicka, Richard Henderson, Kaveh R. Ghazi, ian, gcc,
	Joseph S. Myers

On Sun, 18 Jan 2004, Jan Hubicka wrote:
> If you mark no symbols via special attribute, only main should be
> external.  If you mark more, you get more.

Ok, I see.

> > > I suppose this is mostly equivalent to what LLVM have except for the
> > > fact that list of symbols with external linkage is boundled in the
> > > source itself, instead of being in separate file. Do you have any
> > > experience with the separate file having considerable benefits?
> >
> > I'm not sure if I understand what you mean here, can you please clarify?
>
> You mentioned that instead of using attribute in the source file, you
> get list of functions.  From here the lists are comming?

We use an external file (a linker script basically) to decide the list.
You can also specify the list with a -Wl option.

> > (for example) dynamically load shared objects that call back into the main
> > program.  People will get unhappy if 'gimp' doesn't work in this mode, for
> > example.
>
> I expect people to just mark the interface functions via the attribute.

Ok, great.  :)

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:40   ` Chris Lattner
@ 2004-01-18 22:48     ` Jan Hubicka
  2004-01-18 22:50       ` Chris Lattner
  0 siblings, 1 reply; 45+ messages in thread
From: Jan Hubicka @ 2004-01-18 22:48 UTC (permalink / raw)
  To: Chris Lattner
  Cc: Jan Hubicka, Richard Henderson, Kaveh R. Ghazi, ian, gcc,
	Joseph S. Myers


> On Sun, 18 Jan 2004, Jan Hubicka wrote:
> > > as having internal linkage.  In LLVM, this is accomplished with the
> > > "internalize" pass, which by default marks all symbols internal if the
> > > linked program contains a main (ie, this does not happen for libraries).
> > > This change enables a _lot_ of interprocedural optimizations that would
> > > not be safe to perform otherwise.  Of course the internalize pass can be
> > > completely disabled, or enabled for a list of symbols as needed.
> >
> > In my prototype unit-at-a-time code I have either the default mode,
> > where all external symbols are just external and -fwhole-program mode
> > where all symbols that do have deifnitions are considered internal
> > except for main and symbols marked by "used" attribute.
> 
> But they get emitted to the executable as external?

If you mark no symbols via special attribute, only main should be
external.  If you mark more, you get more.
> 
> > I suppose this is mostly equivalent to what LLVM have except for the
> > fact that list of symbols with external linkage is boundled in the
> > source itself, instead of being in separate file. Do you have any
> > experience with the separate file having considerable benefits?
> 
> I'm not sure if I understand what you mean here, can you please clarify?

You mentioned that instead of using attribute in the source file, you
get list of functions.  From here the lists are comming?
> 
> > > The nice thing about LLVM using the internalize pass is that if it is used
> > > incorrectly, a program will not link.  If you use a "whole program"
> > > compiler incorrectly, it will be silently misoptimized, which IMHO is
> > > _much_ worse.
> >
> > My plan is to make all symbols that are considered local static so it
> > will elliminate this problem.
> 
> Ok, but you should at least think about adding support for programs that
> (for example) dynamically load shared objects that call back into the main
> program.  People will get unhappy if 'gimp' doesn't work in this mode, for
> example.

I expect people to just mark the interface functions via the attribute.

Honza
> 
> -Chris
> 
> -- 
> http://llvm.cs.uiuc.edu/
> http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:42   ` Joseph S. Myers
@ 2004-01-18 22:44     ` Chris Lattner
  0 siblings, 0 replies; 45+ messages in thread
From: Chris Lattner @ 2004-01-18 22:44 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Jan Hubicka, Richard Henderson, Kaveh R. Ghazi, ian, gcc

On Sun, 18 Jan 2004, Joseph S. Myers wrote:

> On Sun, 18 Jan 2004, Jan Hubicka wrote:
>
> > I suppose this is mostly equivalent to what LLVM have except for the
> > fact that list of symbols with external linkage is boundled in the
> > source itself, instead of being in separate file.
> > Do you have any experience with the separate file having considerable
> > benefits?
>
> If you could generate the list from a GNU linker script, you could take
> advantage of such a script in any library hiding internal functions that
> way.  The obvious example is glibc but I don't know to what extent the
> functions written in assembler would inhibit such optimisations.

Exactly.  Also, libstd++ is a great example of a library with a number of
internal symbols, but which is disciplined enough to have a firm grasp of
what is being exported.

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:33 ` Jan Hubicka
  2004-01-18 22:40   ` Chris Lattner
@ 2004-01-18 22:42   ` Joseph S. Myers
  2004-01-18 22:44     ` Chris Lattner
  1 sibling, 1 reply; 45+ messages in thread
From: Joseph S. Myers @ 2004-01-18 22:42 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Chris Lattner, Richard Henderson, Kaveh R. Ghazi, ian, gcc

On Sun, 18 Jan 2004, Jan Hubicka wrote:

> I suppose this is mostly equivalent to what LLVM have except for the
> fact that list of symbols with external linkage is boundled in the
> source itself, instead of being in separate file.
> Do you have any experience with the separate file having considerable
> benefits?

If you could generate the list from a GNU linker script, you could take
advantage of such a script in any library hiding internal functions that
way.  The obvious example is glibc but I don't know to what extent the
functions written in assembler would inhibit such optimisations.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:36 ` Richard Henderson
@ 2004-01-18 22:42   ` Chris Lattner
  0 siblings, 0 replies; 45+ messages in thread
From: Chris Lattner @ 2004-01-18 22:42 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Kaveh R. Ghazi, ian, gcc, Joseph S. Myers

On Sun, 18 Jan 2004, Richard Henderson wrote:

> On Sun, Jan 18, 2004 at 04:37:22PM -0600, Chris Lattner wrote:
> > > One possibility is a switch that says "except for main, nothing
> > > outside these files reference any of the symbols herein defined."
> > > That might get you the same effect as whole-program optimization
> > > without having to have extra info about external runtime libraries.
> >
> > This is _extremely_ dangerous, and in practice, cannot be done.
> [...]
> > The nice thing about LLVM using the internalize pass is that if it is used
> > incorrectly, a program will not link.
>
> We're talking about the *exact* same transformation.

Ok, I guess it depends on how you write the transformation.  Does the
_transformation_ assume it has the whole program, or will it actually do
the analysis to determing what "escapes" out to unknown portions of the
program?  Doing this analysis is nontrivial but worth it.  For a
datapoint, many IPO transformations are run at LLVM compile time (not link
time), to good effect.

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:33 ` Jan Hubicka
@ 2004-01-18 22:40   ` Chris Lattner
  2004-01-18 22:48     ` Jan Hubicka
  2004-01-18 22:42   ` Joseph S. Myers
  1 sibling, 1 reply; 45+ messages in thread
From: Chris Lattner @ 2004-01-18 22:40 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Henderson, Kaveh R. Ghazi, ian, gcc, Joseph S. Myers

On Sun, 18 Jan 2004, Jan Hubicka wrote:
> > as having internal linkage.  In LLVM, this is accomplished with the
> > "internalize" pass, which by default marks all symbols internal if the
> > linked program contains a main (ie, this does not happen for libraries).
> > This change enables a _lot_ of interprocedural optimizations that would
> > not be safe to perform otherwise.  Of course the internalize pass can be
> > completely disabled, or enabled for a list of symbols as needed.
>
> In my prototype unit-at-a-time code I have either the default mode,
> where all external symbols are just external and -fwhole-program mode
> where all symbols that do have deifnitions are considered internal
> except for main and symbols marked by "used" attribute.

But they get emitted to the executable as external?

> I suppose this is mostly equivalent to what LLVM have except for the
> fact that list of symbols with external linkage is boundled in the
> source itself, instead of being in separate file. Do you have any
> experience with the separate file having considerable benefits?

I'm not sure if I understand what you mean here, can you please clarify?

> > The nice thing about LLVM using the internalize pass is that if it is used
> > incorrectly, a program will not link.  If you use a "whole program"
> > compiler incorrectly, it will be silently misoptimized, which IMHO is
> > _much_ worse.
>
> My plan is to make all symbols that are considered local static so it
> will elliminate this problem.

Ok, but you should at least think about adding support for programs that
(for example) dynamically load shared objects that call back into the main
program.  People will get unhappy if 'gimp' doesn't work in this mode, for
example.

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:22       ` Jan Hubicka
@ 2004-01-18 22:37         ` Richard Henderson
  2004-01-19 19:33           ` DJ Delorie
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Henderson @ 2004-01-18 22:37 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Joseph S. Myers, Kaveh R. Ghazi, ian, gcc

On Sun, Jan 18, 2004 at 11:22:01PM +0100, Jan Hubicka wrote:
> What is preventing us from declaring the structure as constant so we
> should get propagation even with current design?

Targets that modify the structure at startup.


r~

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:18 Chris Lattner
  2004-01-18 22:33 ` Jan Hubicka
@ 2004-01-18 22:36 ` Richard Henderson
  2004-01-18 22:42   ` Chris Lattner
  1 sibling, 1 reply; 45+ messages in thread
From: Richard Henderson @ 2004-01-18 22:36 UTC (permalink / raw)
  To: Chris Lattner; +Cc: Kaveh R. Ghazi, ian, gcc, Joseph S. Myers

On Sun, Jan 18, 2004 at 04:37:22PM -0600, Chris Lattner wrote:
> > One possibility is a switch that says "except for main, nothing
> > outside these files reference any of the symbols herein defined."
> > That might get you the same effect as whole-program optimization
> > without having to have extra info about external runtime libraries.
> 
> This is _extremely_ dangerous, and in practice, cannot be done.
[...]
> The nice thing about LLVM using the internalize pass is that if it is used
> incorrectly, a program will not link.

We're talking about the *exact* same transformation.


r~

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:18 Chris Lattner
@ 2004-01-18 22:33 ` Jan Hubicka
  2004-01-18 22:40   ` Chris Lattner
  2004-01-18 22:42   ` Joseph S. Myers
  2004-01-18 22:36 ` Richard Henderson
  1 sibling, 2 replies; 45+ messages in thread
From: Jan Hubicka @ 2004-01-18 22:33 UTC (permalink / raw)
  To: Chris Lattner
  Cc: Richard Henderson, Kaveh R. Ghazi, ian, gcc, Joseph S. Myers

> 
> Richard Henderson wrote:
> > On Sun, Jan 18, 2004 at 09:14:14PM +0000, Joseph S. Myers wrote:
> > > When --enable-intermodule is used, does (or should) the compiler
> > > manage to detect which parts of the target structure are in fact
> > > constant (even without constifying)?
> 
> LLVM is very good at this kind of stuff.

Yeah..
> 
> > However, that sort of optimization requires that you see the *entire*
> > program, not just large parts of it, as with the current intermodule
> > code.  So I expect this sort of thing is relatively far away.
> 
> This is not really true.  At some point, the structure needs to be marked
> as having internal linkage.  In LLVM, this is accomplished with the
> "internalize" pass, which by default marks all symbols internal if the
> linked program contains a main (ie, this does not happen for libraries).
> This change enables a _lot_ of interprocedural optimizations that would
> not be safe to perform otherwise.  Of course the internalize pass can be
> completely disabled, or enabled for a list of symbols as needed.

In my prototype unit-at-a-time code I have either the default mode,
where all external symbols are just external and -fwhole-program mode
where all symbols that do have deifnitions are considered internal
except for main and symbols marked by "used" attribute.

I suppose this is mostly equivalent to what LLVM have except for the
fact that list of symbols with external linkage is boundled in the
source itself, instead of being in separate file.
Do you have any experience with the separate file having considerable
benefits?
> 
> Note that it is quite possible that the user would like to run the
> internalize pass _before_ the whole program is available, for example, to
> prune the public symbols exposed by a library.
> 
> > One possibility is a switch that says "except for main, nothing
> > outside these files reference any of the symbols herein defined."
> > That might get you the same effect as whole-program optimization
> > without having to have extra info about external runtime libraries.
> 
> This is _extremely_ dangerous, and in practice, cannot be done.  A
> compiler _very rarely_ has the entire program to analyze, and must
> therefore be able to handle the fact that there is external code that can
> access program structures (e.g., there can be precompiled libraries (ie,
> libc, libm), dynamically loaded libraries (plugins), etc).
> 
> The nice thing about LLVM using the internalize pass is that if it is used
> incorrectly, a program will not link.  If you use a "whole program"
> compiler incorrectly, it will be silently misoptimized, which IMHO is
> _much_ worse.

My plan is to make all symbols that are considered local static so it
will elliminate this problem.

Honza
> 
> -Chris
> 
> -- 
> http://llvm.cs.uiuc.edu/
> http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 14:09   ` Ian Lance Taylor
@ 2004-01-18 22:25     ` Zack Weinberg
  2004-01-19  0:53       ` Ian Lance Taylor
  2004-01-19  1:18       ` Geoff Keating
  0 siblings, 2 replies; 45+ messages in thread
From: Zack Weinberg @ 2004-01-18 22:25 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Ian Lance Taylor <ian@wasabisystems.com> writes:

> "Zack Weinberg" <zack@codesourcery.com> writes:
>> Furthermore, while a 3% measured speed hit is a concern, I think that
>> trying to win it back by undoing the targetm transformation - in the
>> object files, if not in the source code - is barking up the wrong
>> tree.  Instead we should be looking for ways to avoid having targetm
>> hooks in critical paths in the first place.  It's been my experience
>> that that is a much more fruitful source of optimization
>> opportunities.
>
> I don't have anything against that goal, but it is in conflict with
> the goal of speeding up the compiler.  Simply moving targetm hooks
> obviously can not get you the full speedup.  The full speedup comes
> when an optimizing compiler compiling gcc can see that certain values
> are constants, such as, in my example, the various promote_* functions
> in the target vector.  You can't pull those target hooks out of the
> critical path.  Function calls are on the critical path for a
> non-optimizing compilation of many types of C++ code, and a
> non-optimizing compilation is the case where compilation speed is the
> most important.

This - and further discussion downthread - misses the point I was
trying to make.

You're seeing 3% speedup on some test case by exposing that certain
elements of targetm.calls are compile-time constant.  Here are the
existing elements of that structure:

    bool (*promote_function_args) (tree fntype);
    bool (*promote_function_return) (tree fntype);
    bool (*promote_prototypes) (tree fntype);
    rtx (*struct_value_rtx) (tree fndecl, int incoming);
    bool (*return_in_memory) (tree type, tree fndecl);
    bool (*return_in_msb) (tree type);
    rtx (*expand_builtin_saveregs) (void);
    /* Returns pretend_argument_size.  */
    void (*setup_incoming_varargs) (CUMULATIVE_ARGS *ca, enum machine_mode mode,
				    tree type, int *pretend_arg_size,
                                    int second_time);
    bool (*strict_argument_naming) (CUMULATIVE_ARGS *ca);
    /* Returns true if we should use SETUP_INCOMING_VARARGS and/or
       STRICT_ARGUMENT_NAMING.  */
    bool (*pretend_outgoing_varargs_named) (CUMULATIVE_ARGS *ca);

Furthermore, skimming tm.texi, it looks like there are at least a
hundred more function-call related target macros that haven't yet been
moved into the target vector: of which FUNCTION_ARG is an obvious
example, but there are also things like SPLIT_COMPLEX_ARGS,
PUSH_ARGS_REVERSED, FRAME_GROWS_DOWNWARD, ...

Of course inefficiencies are going to be introduced if we just convert
each macro to a target hook with the same semantics.  But that isn't
the only option on the table.  The right thing is to redesign this
interface so that it doesn't *need* 100+ macros and toggles.  If this
is done properly, then not only should there be no inefficiency
introduced by going through the target vector, but also we would have
something that was straightforward to maintain and straightforward to
add support for new architectures.

As a data point, I am aware of another (proprietary) compiler that
completely isolates the back end from the optimizers, to the point
where the back end module can be swapped out at runtime, and it
benchmarks competitively or faster than GCC on similar input.  So I
don't believe that this is impossible.

zw

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 22:05     ` Richard Henderson
@ 2004-01-18 22:22       ` Jan Hubicka
  2004-01-18 22:37         ` Richard Henderson
  0 siblings, 1 reply; 45+ messages in thread
From: Jan Hubicka @ 2004-01-18 22:22 UTC (permalink / raw)
  To: Richard Henderson, Joseph S. Myers, Kaveh R. Ghazi, ian, gcc

> On Sun, Jan 18, 2004 at 09:14:14PM +0000, Joseph S. Myers wrote:
> > When --enable-intermodule is used, does (or should) the compiler manage to
> > detect which parts of the target structure are in fact constant (even
> > without constifying)?
> 
> I'm certain that it doesn't.
> 
> It's not inconcievable that a compiler could not that there are 
> never any writes to a structure, promote it to readonly, and then
> constant propagate the values out of that structure.
> 
> However, that sort of optimization requires that you see the *entire*
> program, not just large parts of it, as with the current intermodule
> code.  So I expect this sort of thing is relatively far away.
> 
> One possibility is a switch that says "except for main, nothing 
> outside these files reference any of the symbols herein defined."
> That might get you the same effect as whole-program optimization
> without having to have extra info about external runtime libraries.

I do have such prototype of -fwhole-program optimization.  What is
preventing me from putting it into tree-SSA branch is that I don't like
the symbols that are considered local to appear as external symbols in
output object file and I am not sure whether frobbing of TREE_PUBLIC
flag is best idea around.

I also hacked up Makefiles to use it, but with our current way to do IPA
it means that all backend functions are parsed and optimized over and
over for each frontend binary that results in verly long bootstrap times
and memory consumption.

What is preventing us from declaring the structure as constant so we
should get propagation even with current design?

Honza
> 
> 
> 
> r~

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

* Re: Can we speed up the gcc_target structure?
@ 2004-01-18 22:18 Chris Lattner
  2004-01-18 22:33 ` Jan Hubicka
  2004-01-18 22:36 ` Richard Henderson
  0 siblings, 2 replies; 45+ messages in thread
From: Chris Lattner @ 2004-01-18 22:18 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Kaveh R. Ghazi, ian, gcc, Joseph S. Myers


Richard Henderson wrote:
> On Sun, Jan 18, 2004 at 09:14:14PM +0000, Joseph S. Myers wrote:
> > When --enable-intermodule is used, does (or should) the compiler
> > manage to detect which parts of the target structure are in fact
> > constant (even without constifying)?

LLVM is very good at this kind of stuff.

> However, that sort of optimization requires that you see the *entire*
> program, not just large parts of it, as with the current intermodule
> code.  So I expect this sort of thing is relatively far away.

This is not really true.  At some point, the structure needs to be marked
as having internal linkage.  In LLVM, this is accomplished with the
"internalize" pass, which by default marks all symbols internal if the
linked program contains a main (ie, this does not happen for libraries).
This change enables a _lot_ of interprocedural optimizations that would
not be safe to perform otherwise.  Of course the internalize pass can be
completely disabled, or enabled for a list of symbols as needed.

Note that it is quite possible that the user would like to run the
internalize pass _before_ the whole program is available, for example, to
prune the public symbols exposed by a library.

> One possibility is a switch that says "except for main, nothing
> outside these files reference any of the symbols herein defined."
> That might get you the same effect as whole-program optimization
> without having to have extra info about external runtime libraries.

This is _extremely_ dangerous, and in practice, cannot be done.  A
compiler _very rarely_ has the entire program to analyze, and must
therefore be able to handle the fact that there is external code that can
access program structures (e.g., there can be precompiled libraries (ie,
libc, libm), dynamically loaded libraries (plugins), etc).

The nice thing about LLVM using the internalize pass is that if it is used
incorrectly, a program will not link.  If you use a "whole program"
compiler incorrectly, it will be silently misoptimized, which IMHO is
_much_ worse.

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 21:14   ` Joseph S. Myers
@ 2004-01-18 22:05     ` Richard Henderson
  2004-01-18 22:22       ` Jan Hubicka
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Henderson @ 2004-01-18 22:05 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: Kaveh R. Ghazi, ian, gcc

On Sun, Jan 18, 2004 at 09:14:14PM +0000, Joseph S. Myers wrote:
> When --enable-intermodule is used, does (or should) the compiler manage to
> detect which parts of the target structure are in fact constant (even
> without constifying)?

I'm certain that it doesn't.

It's not inconcievable that a compiler could not that there are 
never any writes to a structure, promote it to readonly, and then
constant propagate the values out of that structure.

However, that sort of optimization requires that you see the *entire*
program, not just large parts of it, as with the current intermodule
code.  So I expect this sort of thing is relatively far away.

One possibility is a switch that says "except for main, nothing 
outside these files reference any of the symbols herein defined."
That might get you the same effect as whole-program optimization
without having to have extra info about external runtime libraries.



r~

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 13:58 ` Kaveh R. Ghazi
  2004-01-18 19:54   ` Ian Lance Taylor
@ 2004-01-18 21:14   ` Joseph S. Myers
  2004-01-18 22:05     ` Richard Henderson
  1 sibling, 1 reply; 45+ messages in thread
From: Joseph S. Myers @ 2004-01-18 21:14 UTC (permalink / raw)
  To: Kaveh R. Ghazi; +Cc: ian, gcc

On Sun, 18 Jan 2004, Kaveh R. Ghazi wrote:

> Something I considered was const-ifying the targetm structure so that
> GCC might optimize some of the call points better.  This would work,
> but for the unfortunate tendency of GCC to modify these values at
> runtime.  I can work around that by inserting an extra function layer,
> except for targetm members that aren't functions already themselves.
> Take a look at the targetm.asm_out.unaligned_op.di assignment in
> sparc.c

When --enable-intermodule is used, does (or should) the compiler manage to
detect which parts of the target structure are in fact constant (even
without constifying)?

-- 
Joseph S. Myers
jsm@polyomino.org.uk

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 20:10     ` Richard Henderson
@ 2004-01-18 20:17       ` Ian Lance Taylor
  0 siblings, 0 replies; 45+ messages in thread
From: Ian Lance Taylor @ 2004-01-18 20:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Kaveh R. Ghazi, gcc

Richard Henderson <rth@redhat.com> writes:

> I think perhaps we might be willing to move *some* things back to
> Where they can be seen to be compile-time constants.  However, 
> anything we move back had better be constant.

I think one issue is that there are things which are compile-time
constants for some platforms but not for others.  Those are the types
of things found in targetm.calls, for example.  Or, e.g.,
BYTES_BIG_ENDIAN, although that is not (yet) in the target vector.

> I do not want anyone to be tempted to do sneak more and more complex
> macros back into header files in the name of optimization.

I certainly agree with that.

Ian

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 19:54   ` Ian Lance Taylor
@ 2004-01-18 20:10     ` Richard Henderson
  2004-01-18 20:17       ` Ian Lance Taylor
  0 siblings, 1 reply; 45+ messages in thread
From: Richard Henderson @ 2004-01-18 20:10 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Kaveh R. Ghazi, gcc

I think perhaps we might be willing to move *some* things back to
Where they can be seen to be compile-time constants.  However, 
anything we move back had better be constant.

I do not want anyone to be tempted to do sneak more and more complex
macros back into header files in the name of optimization.


r~

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18 13:58 ` Kaveh R. Ghazi
@ 2004-01-18 19:54   ` Ian Lance Taylor
  2004-01-18 20:10     ` Richard Henderson
  2004-01-18 21:14   ` Joseph S. Myers
  1 sibling, 1 reply; 45+ messages in thread
From: Ian Lance Taylor @ 2004-01-18 19:54 UTC (permalink / raw)
  To: Kaveh R. Ghazi; +Cc: gcc

"Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> writes:

> I recently had an offline discussion with Zack et al where I tried to
> prove the same point.  I did almost exactly the same thing you did,
> however my results showed only a 0.3% diff, about one tenth the impact
> you saw.
> 
> Beyond the difference in hardware, I'd like to know if anything else
> might explain how your results vary so much from mine.  I've included
> some detail from the original offline message below so that my results
> are reproducible.
> 
> E.g. I'd like to know what you compiled and at what optimization level
> when you measured the speed change.
> 
> Since my results were so small, I didn't bother suggesting we undo or
> "fix" it.  However your if your results are more typical we may want
> to consider doing something to reduce the impact.

I have to admit that testing with some test cases from Bugzilla I'm
only seeing about a 1% improvement.  I see that with, e.g., the C++
test case from PR 2692.  For only 1%, I don't know whether this is
worth pursuing.  On the other hand, I only converted part of the
target vector, and the problem is likely to get worse over time.  This
is compiling without optimization.

I've appended the patch I'm using.  Note that I would expect better
results from this patch than from yours, since I'm actually
eliminating function calls entirely and replacing them with constants.

Ian

Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.275
diff -p -u -r1.275 builtins.c
--- builtins.c	15 Jan 2004 07:25:21 -0000	1.275
+++ builtins.c	18 Jan 2004 19:11:16 -0000
@@ -924,7 +924,7 @@ apply_args_size (void)
 
       /* The second value is the structure value address unless this is
 	 passed as an "invisible" first argument.  */
-      if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
+      if (TARGETM_CALLS_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
 	size += GET_MODE_SIZE (Pmode);
 
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -1099,7 +1099,7 @@ expand_builtin_apply_args_1 (void)
   rtx registers, tem;
   int size, align, regno;
   enum machine_mode mode;
-  rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
+  rtx struct_incoming_value = TARGETM_CALLS_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
 
   /* Create a block where the arg-pointer, structure value address,
      and argument registers can be saved.  */
@@ -1107,7 +1107,7 @@ expand_builtin_apply_args_1 (void)
 
   /* Walk past the arg-pointer and structure value address.  */
   size = GET_MODE_SIZE (Pmode);
-  if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
+  if (TARGETM_CALLS_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
     size += GET_MODE_SIZE (Pmode);
 
   /* Save each register used in calling a function to the block.  */
@@ -1201,7 +1201,7 @@ expand_builtin_apply (rtx function, rtx 
   rtx incoming_args, result, reg, dest, src, call_insn;
   rtx old_stack_level = 0;
   rtx call_fusage = 0;
-  rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
+  rtx struct_value = TARGETM_CALLS_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
 
   arguments = convert_memory_address (Pmode, arguments);
 
@@ -3792,7 +3792,7 @@ expand_builtin_saveregs (void)
   start_sequence ();
 
   /* Do whatever the machine needs done in this case.  */
-  val = targetm.calls.expand_builtin_saveregs ();
+  val = TARGETM_CALLS_EXPAND_BUILTIN_SAVEREGS ();
 
   seq = get_insns ();
   end_sequence ();
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.470
diff -p -u -r1.470 c-decl.c
--- c-decl.c	13 Jan 2004 02:52:33 -0000	1.470
+++ c-decl.c	18 Jan 2004 19:11:18 -0000
@@ -2669,7 +2669,7 @@ start_decl (tree declarator, tree declsp
   decl_attributes (&decl, attributes, 0);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
+      && TARGETM_CALLS_PROMOTE_PROTOTYPES (TREE_TYPE (decl)))
     {
       tree ce = declarator;
 
@@ -5908,7 +5908,7 @@ store_parm_decls_oldstyle (void)
 		     useful for argument types like uid_t.  */
 		  DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
 
-		  if (targetm.calls.promote_prototypes (TREE_TYPE (current_function_decl))
+		  if (TARGETM_CALLS_PROMOTE_PROTOTYPES (TREE_TYPE (current_function_decl))
 		      && INTEGRAL_TYPE_P (TREE_TYPE (parm))
 		      && TYPE_PRECISION (TREE_TYPE (parm))
 		      < TYPE_PRECISION (integer_type_node))
@@ -6061,7 +6061,7 @@ finish_function (void)
     }
 
   if (TREE_CODE (fndecl) == FUNCTION_DECL
-      && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
+      && TARGETM_CALLS_PROMOTE_PROTOTYPES (TREE_TYPE (fndecl)))
     {
       tree args = DECL_ARGUMENTS (fndecl);
       for (; args; args = TREE_CHAIN (args))
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.272
diff -p -u -r1.272 c-typeck.c
--- c-typeck.c	16 Jan 2004 07:20:28 -0000	1.272
+++ c-typeck.c	18 Jan 2004 19:11:20 -0000
@@ -1915,7 +1915,7 @@ convert_arguments (tree typelist, tree v
 					        (char *) 0, /* arg passing  */
 						fundecl, name, parmnum + 1);
 
-	      if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
+	      if (TARGETM_CALLS_PROMOTE_PROTOTYPES (fundecl ? TREE_TYPE (fundecl) : 0)
 		  && INTEGRAL_TYPE_P (type)
 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
 		parmval = default_conversion (parmval);
@@ -3683,7 +3683,7 @@ c_convert_parm_for_inlining (tree parm, 
   ret = convert_for_assignment (type, value,
 				(char *) 0 /* arg passing  */, fn,
 				DECL_NAME (fn), argnum);
-  if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
+  if (TARGETM_CALLS_PROMOTE_PROTOTYPES (TREE_TYPE (fn))
       && INTEGRAL_TYPE_P (type)
       && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
     ret = default_conversion (ret);
Index: calls.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/calls.c,v
retrieving revision 1.315
diff -p -u -r1.315 calls.c
--- calls.c	16 Jan 2004 01:44:06 -0000	1.315
+++ calls.c	18 Jan 2004 19:11:21 -0000
@@ -1192,7 +1192,7 @@ initialize_argument_information (int num
       mode = TYPE_MODE (type);
       unsignedp = TREE_UNSIGNED (type);
 
-      if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0))
+      if (TARGETM_CALLS_PROMOTE_FUNCTION_ARGS (fndecl ? TREE_TYPE (fndecl) : 0))
 	mode = promote_mode (type, mode, &unsignedp, 1);
 
       args[i].unsignedp = unsignedp;
@@ -2030,7 +2030,7 @@ fix_unsafe_tree (tree t)
 static bool
 shift_returned_value (tree type, rtx *value)
 {
-  if (targetm.calls.return_in_msb (type))
+  if (TARGETM_CALLS_RETURN_IN_MSB (type))
     {
       HOST_WIDE_INT shift;
 
@@ -2226,7 +2226,7 @@ expand_call (tree exp, rtx target, int i
       flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
     }
 
-  struct_value = targetm.calls.struct_value_rtx (fndecl ? TREE_TYPE (fndecl) : 0, 0);
+  struct_value = TARGETM_CALLS_STRUCT_VALUE_RTX (fndecl ? TREE_TYPE (fndecl) : 0, 0);
 
   /* Warn if this value is an aggregate type,
      regardless of which calling convention we are using for it.  */
@@ -2406,28 +2406,28 @@ expand_call (tree exp, rtx target, int i
   /* Compute 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.
+     TARGETM_CALLS_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 TARGETM_CALLS_PRETEND_OUTGOING_VARARGS_NAMED() returns
+     nonzero, and TARGETM_CALLS_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 TARGETM_CALLS_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 ((targetm.calls.strict_argument_naming (&args_so_far)
-       || ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
+  if ((TARGETM_CALLS_STRICT_ARGUMENT_NAMING (&args_so_far)
+       || ! TARGETM_CALLS_PRETEND_OUTGOING_VARARGS_NAMED (&args_so_far))
       && type_arg_types != 0)
     n_named_args
       = (list_length (type_arg_types)
 	 /* Don't include the last named arg.  */
-	 - (targetm.calls.strict_argument_naming (&args_so_far) ? 0 : 1)
+	 - (TARGETM_CALLS_STRICT_ARGUMENT_NAMING (&args_so_far) ? 0 : 1)
 	 /* Count the struct value address, if it is passed as a parm.  */
 	 + structure_value_addr_parm);
   else
@@ -3344,7 +3344,7 @@ expand_call (tree exp, rtx target, int i
 	  target = copy_to_reg (valreg);
 	}
 
-      if (targetm.calls.promote_function_return(funtype))
+      if (TARGETM_CALLS_PROMOTE_FUNCTION_RETURN(funtype))
 	{
       /* If we promoted this return value, make the proper SUBREG.  TARGET
 	 might be const0_rtx here, so be careful.  */
@@ -3685,7 +3685,7 @@ emit_library_call_value_1 (int retval, r
   int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
   char *initial_stack_usage_map = stack_usage_map;
 
-  rtx struct_value = targetm.calls.struct_value_rtx (0, 0);
+  rtx struct_value = TARGETM_CALLS_STRUCT_VALUE_RTX (0, 0);
 
 #ifdef REG_PARM_STACK_SPACE
 #ifdef MAYBE_REG_PARM_STACK_SPACE
Index: combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.400
diff -p -u -r1.400 combine.c
--- combine.c	12 Jan 2004 19:42:42 -0000	1.400
+++ combine.c	18 Jan 2004 19:11:25 -0000
@@ -806,7 +806,7 @@ setup_incoming_promotions (void)
   int unsignedp;
   rtx first = get_insns ();
 
-  if (targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
+  if (TARGETM_CALLS_PROMOTE_FUNCTION_ARGS (TREE_TYPE (cfun->decl)))
     {
 #ifndef OUTGOING_REGNO
 #define OUTGOING_REGNO(N) N
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.615
diff -p -u -r1.615 expr.c
--- expr.c	13 Jan 2004 23:13:58 -0000	1.615
+++ expr.c	18 Jan 2004 19:11:28 -0000
@@ -2137,7 +2137,7 @@ copy_blkmode_from_reg (rtx tgtblk, rtx s
      holds if the structure is returned at the most significant
      end of the register.  */
   if (bytes % UNITS_PER_WORD != 0
-      && (targetm.calls.return_in_msb (type)
+      && (TARGETM_CALLS_RETURN_IN_MSB (type)
 	  ? !BYTES_BIG_ENDIAN
 	  : BYTES_BIG_ENDIAN))
     padding_correction
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.304
diff -p -u -r1.304 final.c
--- final.c	9 Jan 2004 20:03:53 -0000	1.304
+++ final.c	18 Jan 2004 19:11:29 -0000
@@ -1406,7 +1406,7 @@ profile_function (FILE *file ATTRIBUTE_U
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
   int sval = current_function_returns_struct;
-  rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
+  rtx svrtx = TARGETM_CALLS_STRUCT_VALUE_RTX (TREE_TYPE (current_function_decl), 1);
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
   int cxt = current_function_needs_context;
 #endif
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.483
diff -p -u -r1.483 function.c
--- function.c	13 Jan 2004 01:58:35 -0000	1.483
+++ function.c	18 Jan 2004 19:11:31 -0000
@@ -4242,7 +4242,7 @@ aggregate_value_p (tree exp, tree fntype
 
   if (TREE_CODE (type) == VOID_TYPE)
     return 0;
-  if (targetm.calls.return_in_memory (type, fntype))
+  if (TARGETM_CALLS_RETURN_IN_MEMORY (type, fntype))
     return 1;
   /* Types that are TREE_ADDRESSABLE must be constructed in memory,
      and thus can't be returned in registers.  */
@@ -4321,7 +4321,7 @@ assign_parms (tree fndecl)
   /* If struct value address is treated as the first argument, make it so.  */
   if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
       && ! current_function_returns_pcc_struct
-      && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
+      && TARGETM_CALLS_STRUCT_VALUE_RTX (TREE_TYPE (fndecl), 1) == 0)
     {
       tree type = build_pointer_type (TREE_TYPE (fntype));
 
@@ -4391,7 +4391,7 @@ assign_parms (tree fndecl)
       /* Set NAMED_ARG if this arg should be treated as a named arg.  For
 	 most machines, if this is a varargs/stdarg function, then we treat
 	 the last named arg as if it were anonymous too.  */
-      named_arg = targetm.calls.strict_argument_naming (&args_so_far) ? 1 : ! last_named;
+      named_arg = TARGETM_CALLS_STRICT_ARGUMENT_NAMING (&args_so_far) ? 1 : ! last_named;
 
       if (TREE_TYPE (parm) == error_mark_node
 	  /* This can happen after weird syntax errors
@@ -4456,7 +4456,7 @@ assign_parms (tree fndecl)
 
       promoted_mode = passed_mode;
 
-      if (targetm.calls.promote_function_args (TREE_TYPE (fndecl)))
+      if (TARGETM_CALLS_PROMOTE_FUNCTION_ARGS (TREE_TYPE (fndecl)))
 	{
 	  /* Compute the mode in which the arg is actually extended to.  */
 	  unsignedp = TREE_UNSIGNED (passed_type);
@@ -4489,7 +4489,7 @@ assign_parms (tree fndecl)
       if (last_named && !varargs_setup)
 	{
 	  int varargs_pretend_bytes = 0;
-	  targetm.calls.setup_incoming_varargs (&args_so_far, promoted_mode,
+	  TARGETM_CALLS_SETUP_INCOMING_VARARGS (&args_so_far, promoted_mode,
 						passed_type,
 						&varargs_pretend_bytes, 0);
 	  varargs_setup = 1;
@@ -4520,7 +4520,7 @@ assign_parms (tree fndecl)
       if (!in_regs && !named_arg)
 	{
 	  int pretend_named =
-	    targetm.calls.pretend_outgoing_varargs_named (&args_so_far);
+	    TARGETM_CALLS_PRETEND_OUTGOING_VARARGS_NAMED (&args_so_far);
 	  if (pretend_named)
 	    {
 #ifdef FUNCTION_INCOMING_ARG
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.342
diff -p -u -r1.342 stmt.c
--- stmt.c	16 Jan 2004 07:20:28 -0000	1.342
+++ stmt.c	18 Jan 2004 19:11:35 -0000
@@ -2963,7 +2963,7 @@ shift_return_value (rtx val)
   tree type;
 
   type = TREE_TYPE (DECL_RESULT (current_function_decl));
-  if (targetm.calls.return_in_msb (type))
+  if (TARGETM_CALLS_RETURN_IN_MSB (type))
     {
       rtx target;
       HOST_WIDE_INT shift;
@@ -3010,7 +3010,7 @@ expand_value_return (rtx val)
   if (return_reg != val)
     {
       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
-      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+      if (TARGETM_CALLS_PROMOTE_FUNCTION_RETURN (TREE_TYPE (current_function_decl)))
       {
 	int unsignedp = TREE_UNSIGNED (type);
 	enum machine_mode old_mode
@@ -3172,7 +3172,7 @@ expand_return (tree retval)
 	 holds if the structure is returned at the most significant
 	 end of the register.  */
       if (bytes % UNITS_PER_WORD != 0
-	  && (targetm.calls.return_in_msb (TREE_TYPE (retval_rhs))
+	  && (TARGETM_CALLS_RETURN_IN_MSB (TREE_TYPE (retval_rhs))
 	      ? !BYTES_BIG_ENDIAN
 	      : BYTES_BIG_ENDIAN))
 	padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.74
diff -p -u -r1.74 target.h
--- target.h	14 Jan 2004 21:59:30 -0000	1.74
+++ target.h	18 Jan 2004 19:11:35 -0000
@@ -433,9 +434,63 @@ struct gcc_target
 				    tree type, int *pretend_arg_size, int second_time);
     bool (*strict_argument_naming) (CUMULATIVE_ARGS *ca);
     /* Returns true if we should use SETUP_INCOMING_VARARGS and/or
-       targetm.calls.strict_argument_naming().  */
+       TARGETM_CALLS_STRICT_ARGUMENT_NAMING().  */
     bool (*pretend_outgoing_varargs_named) (CUMULATIVE_ARGS *ca);
   } calls;
 };
 
 extern struct gcc_target targetm;
+
+#ifndef TARGETM_CALLS_PROMOTE_FUNCTION_ARGS
+#define TARGETM_CALLS_PROMOTE_FUNCTION_ARGS(FNTYPE) \
+  targetm.calls.promote_function_args ((FNTYPE))
+#endif
+
+#ifndef TARGETM_CALLS_PROMOTE_FUNCTION_RETURN
+#define TARGETM_CALLS_PROMOTE_FUNCTION_RETURN(FNTYPE) \
+  targetm.calls.promote_function_return ((FNTYPE))
+#endif
+
+#ifndef TARGETM_CALLS_PROMOTE_PROTOTYPES
+#define TARGETM_CALLS_PROMOTE_PROTOTYPES(FNTYPE) \
+  targetm.calls.promote_prototypes ((FNTYPE))
+#endif
+
+#ifndef TARGETM_CALLS_STRUCT_VALUE_RTX
+#define TARGETM_CALLS_STRUCT_VALUE_RTX(FNDECL, INCOMING) \
+  targetm.calls.struct_value_rtx ((FNDECL), (INCOMING))
+#endif
+
+#ifndef TARGETM_CALLS_RETURN_IN_MEMORY
+#define TARGETM_CALLS_RETURN_IN_MEMORY(TYPE, FNDECL) \
+  targetm.calls.return_in_memory ((TYPE), (FNDECL))
+#endif
+
+#ifndef TARGETM_CALLS_RETURN_IN_MSB
+#define TARGETM_CALLS_RETURN_IN_MSB(TYPE) \
+  targetm.calls.return_in_msb ((TYPE))
+#endif
+
+#ifndef TARGETM_CALLS_EXPAND_BUILTIN_SAVEREGS
+#define TARGETM_CALLS_EXPAND_BUILTIN_SAVEREGS() \
+  targetm.calls.expand_builtin_saveregs ()
+#endif
+
+#ifndef TARGETM_CALLS_SETUP_INCOMING_VARARGS
+#define TARGETM_CALLS_SETUP_INCOMING_VARARGS(CA, MODE, TYPE, \
+					     PRETEND_ARG_SIZE, \
+					     SECOND_TIME) \
+  targetm.calls.setup_incoming_varargs ((CA), (MODE), (TYPE), \
+					(PRETEND_ARG_SIZE), \
+				        (SECOND_TIME))
+#endif
+
+#ifndef TARGETM_CALLS_STRICT_ARGUMENT_NAMING
+#define TARGETM_CALLS_STRICT_ARGUMENT_NAMING(CA) \
+  targetm.calls.strict_argument_naming((CA))
+#endif
+
+#ifndef TARGETM_CALLS_PRETEND_OUTGOING_VARARGS_NAMED
+#define TARGETM_CALLS_PRETEND_OUTGOING_VARARGS_NAMED(CA) \
+  targetm.calls.pretend_outgoing_varargs_named((CA))
+#endif
Index: targhooks.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/targhooks.c,v
retrieving revision 2.12
diff -p -u -r2.12 targhooks.c
--- targhooks.c	15 Jan 2004 07:21:03 -0000	2.12
+++ targhooks.c	18 Jan 2004 19:11:35 -0000
@@ -184,7 +184,7 @@ default_pretend_outgoing_varargs_named(C
 #ifdef SETUP_INCOMING_VARARGS
   return 1;
 #else
-  return (targetm.calls.setup_incoming_varargs != default_setup_incoming_varargs);
+  return (TARGETM_CALLS_SETUP_INCOMING_VARARGS != default_setup_incoming_varargs);
 #endif
 }
 
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.368
diff -p -u -r1.368 i386.h
--- config/i386/i386.h	14 Jan 2004 23:07:04 -0000	1.368
+++ config/i386/i386.h	18 Jan 2004 19:11:39 -0000
@@ -3172,6 +3172,21 @@ struct machine_function GTY(())
 #define X86_FILE_START_VERSION_DIRECTIVE false
 #define X86_FILE_START_FLTUSED false
 
+#define TARGETM_CALLS_PROMOTE_FUNCTION_ARGS(FNTYPE) false
+#define TARGETM_CALLS_PROMOTE_FUNCTION_RETURN(FNTYPE) false
+#define TARGETM_CALLS_PROMOTE_PROTOTYPES(FNTYPE) true
+#define TARGETM_CALLS_STRUCT_VALUE_RTX(FNDECL, INCOMING) 0
+#define TARGETM_CALLS_RETURN_IN_MEMORY(TYPE, FNDECL) RETURN_IN_MEMORY (type)
+#define TARGETM_CALLS_RETURN_IN_MSB(TYPE) false
+#define TARGETM_CALLS_SETUP_INCOMING_VARARGS(CA, MODE, TYPE, \
+					     PRETEND_ARG_SIZE, \
+					     SECOND_TIME) \
+  SETUP_INCOMING_VARARGS ((*CA), (MODE), (TYPE), (*PRETEND_ARG_SIZE), \
+			  (SECOND_TIME))
+#define TARGETM_CALLS_STRICT_ARGUMENT_NAMING(CA) 0
+#define TARGETM_CALLS_PRETEND_OUTGOING_VARARGS_NAMED(CA) 1
+
+
 /*
 Local variables:
 version-control: t

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18  9:03 ` Zack Weinberg
@ 2004-01-18 14:09   ` Ian Lance Taylor
  2004-01-18 22:25     ` Zack Weinberg
  0 siblings, 1 reply; 45+ messages in thread
From: Ian Lance Taylor @ 2004-01-18 14:09 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc

"Zack Weinberg" <zack@codesourcery.com> writes:

> Any change along these lines loses what I think is a critical property
> of the target vector, which is that modifications to the target-specific
> code on the far side of it do *not* require recompilation of the
> entire machine-independent compiler.
> 
> I consider it a desirable and achievable goal to be able to swap out
> the entire back end without rebuilding any of the optimizers; this
> entails having *everything* go through the target vector or some other
> sort of link-time interface.  (For instance, I see no need to change
> the way recog.c interacts with insn-recog.c for this purpose.)
> 
> Furthermore, while a 3% measured speed hit is a concern, I think that
> trying to win it back by undoing the targetm transformation - in the
> object files, if not in the source code - is barking up the wrong
> tree.  Instead we should be looking for ways to avoid having targetm
> hooks in critical paths in the first place.  It's been my experience
> that that is a much more fruitful source of optimization
> opportunities.

I don't have anything against that goal, but it is in conflict with
the goal of speeding up the compiler.  Simply moving targetm hooks
obviously can not get you the full speedup.  The full speedup comes
when an optimizing compiler compiling gcc can see that certain values
are constants, such as, in my example, the various promote_* functions
in the target vector.  You can't pull those target hooks out of the
critical path.  Function calls are on the critical path for a
non-optimizing compilation of many types of C++ code, and a
non-optimizing compilation is the case where compilation speed is the
most important.

At best you can replace target hook function calls with target hook
memory references.  For example, you could somehow detect that
promote_function_args always returns false for the i386.  I'm not sure
how to do that cleanly, without adding a dependency between target
hooks which would be a source of future bugs, but it may be possible.
But even a memory reference is going to be slower than a compile-time
constant.

Also, as more and more control moves into the target vector, which I
think we all agree is a good goal, it will slow down the compiler more
and more.

As I say, your goal is a good one.  And it may trump the goal of
maximizing compiler speed.  Although I will note that your goal
benefits only compiler developers.  And maximizing compiler speed
benefits compiler users.  And obviously we could have a configure
option which forced all calls to go through the target vector, as I
discussed in my original message--that configure option could then
affect the Makefile dependencies.  That would make it easier for
developers, at the cost of possibly introducing unnoticed bugs.

Ian

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18  8:37 Ian Lance Taylor
  2004-01-18  9:03 ` Zack Weinberg
  2004-01-18 11:30 ` Joseph S. Myers
@ 2004-01-18 13:58 ` Kaveh R. Ghazi
  2004-01-18 19:54   ` Ian Lance Taylor
  2004-01-18 21:14   ` Joseph S. Myers
  2004-01-19  1:12 ` Geoff Keating
  3 siblings, 2 replies; 45+ messages in thread
From: Kaveh R. Ghazi @ 2004-01-18 13:58 UTC (permalink / raw)
  To: ian; +Cc: gcc

 > More recently, some of those parameters have moved into the gcc_target
 > structure.  They are still checked at run time, but now the if
 > condition never has a constant value.  It always requires fetching a
 > value from memory in the target vector, and often requires calling a
 > function.  This results in cleaner, more comprehensible code.
 > 
 > However, it also slows the compiler down.

Ian,

I recently had an offline discussion with Zack et al where I tried to
prove the same point.  I did almost exactly the same thing you did,
however my results showed only a 0.3% diff, about one tenth the impact
you saw.

Beyond the difference in hardware, I'd like to know if anything else
might explain how your results vary so much from mine.  I've included
some detail from the original offline message below so that my results
are reproducible.

E.g. I'd like to know what you compiled and at what optimization level
when you measured the speed change.

Since my results were so small, I didn't bother suggesting we undo or
"fix" it.  However your if your results are more typical we may want
to consider doing something to reduce the impact.

Something I considered was const-ifying the targetm structure so that
GCC might optimize some of the call points better.  This would work,
but for the unfortunate tendency of GCC to modify these values at
runtime.  I can work around that by inserting an extra function layer,
except for targetm members that aren't functions already themselves.
Take a look at the targetm.asm_out.unaligned_op.di assignment in
sparc.c

		Thanks,
		--Kaveh


---original-message-below---------------------------------------------

Ok I did some testing.  I un-hook-ized GCC by replacing all accesses
through `targetm' with the macro representing the function or value
which targetm would have returned.  The difference measures the
overhead of bouncing through pointers versus direct function calls or
explicit values.  It _doesn't_ measure the effect of outlining any of
the code that used to be inline macros.

The patch bootstrapped on sparc-sun-solaris2.7 configured with
--disable-checking --enable-multilib=no --disable-nls.  The change
resulted in a net shrinkage of cc1 by about 6k.  I then timed
compiling GCC's own combine.i at -S -O0 ten times with a baseline
(configured identically) and the patched gcc both checked out on the
morning of 12/31/2003.  The resulting .s files were identical.

Some notes:

1.  I had to externalize some macro overrides and function definitions
    set in targetm in sparc.c so things were visible where necessary.
    If you want to try this patch on another system, you'll have to do
    the same to your cpu.c file and other files in config/cpu.

2.  Some accesses through targetm were to (guarded) NULL pointers.
    When visible directly, GCC doesn't like (*NULL)() so I left them
    as originally written.  If you port to another cpu, you'll want to
    change those as necessary.

3.  I suspect using -O0 on combine.i would tend to magnify any
    difference since it avoids piggy algorithms used during
    optimization.  I.e. at -O2, the results will vanish more.


Anyway, I measured a tiny but repeatable difference in compile time of
around 0.3% (+- 0.1%).  Since it's so small, we probably don't care
since we're supposedly getting some benefits from hookizing.

We still don't know what effect (if any) outlining all the bits of
code which used to reside in macros had.  I.e. in this test we're
still calling functions everywhere, but plain foo() generates less
code than (*targetm.blah.blah.foo) () at least on sparc.

If anyone wants to play with the patch, here it is.

		--Kaveh


diff -rup orig/egcc-CVS20031230/gcc/alias.c egcc-CVS20031230/gcc/alias.c
--- orig/egcc-CVS20031230/gcc/alias.c	2003-12-21 20:01:11.000000000 -0500
+++ egcc-CVS20031230/gcc/alias.c	2004-01-01 13:03:42.198449000 -0500
@@ -2600,7 +2600,7 @@ mark_constant_function (void)
       || DECL_IS_PURE (current_function_decl)
       || TREE_THIS_VOLATILE (current_function_decl)
       || current_function_has_nonlocal_goto
-      || !(*targetm.binds_local_p) (current_function_decl))
+      || ! TARGET_BINDS_LOCAL_P (current_function_decl))
     return;
 
   /* A loop might not return which counts as a side effect.  */
diff -rup orig/egcc-CVS20031230/gcc/attribs.c egcc-CVS20031230/gcc/attribs.c
--- orig/egcc-CVS20031230/gcc/attribs.c	2003-08-20 18:23:59.000000000 -0400
+++ egcc-CVS20031230/gcc/attribs.c	2004-01-01 13:06:46.305771000 -0500
@@ -60,7 +60,7 @@ init_attributes (void)
   attribute_tables[0] = lang_hooks.common_attribute_table;
   attribute_tables[1] = lang_hooks.attribute_table;
   attribute_tables[2] = lang_hooks.format_attribute_table;
-  attribute_tables[3] = targetm.attribute_table;
+  attribute_tables[3] = TARGET_ATTRIBUTE_TABLE;
 
   /* Translate NULL pointers to pointers to the empty table.  */
   for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
@@ -145,7 +145,7 @@ decl_attributes (tree *node, tree attrib
   if (!attributes_initialized)
     init_attributes ();
 
-  (*targetm.insert_attributes) (*node, &attributes);
+  TARGET_INSERT_ATTRIBUTES (*node, &attributes);
 
   for (a = attributes; a; a = TREE_CHAIN (a))
     {
diff -rup orig/egcc-CVS20031230/gcc/bb-reorder.c egcc-CVS20031230/gcc/bb-reorder.c
--- orig/egcc-CVS20031230/gcc/bb-reorder.c	2003-12-20 20:01:06.000000000 -0500
+++ egcc-CVS20031230/gcc/bb-reorder.c	2004-01-01 13:06:18.707076000 -0500
@@ -1075,7 +1075,7 @@ reorder_basic_blocks (void)
   if (n_basic_blocks <= 1)
     return;
 
-  if ((* targetm.cannot_modify_jumps_p) ())
+  if (TARGET_CANNOT_MODIFY_JUMPS_P ())
     return;
 
   timevar_push (TV_REORDER_BLOCKS);
diff -rup orig/egcc-CVS20031230/gcc/bt-load.c egcc-CVS20031230/gcc/bt-load.c
--- orig/egcc-CVS20031230/gcc/bt-load.c	2003-12-30 20:01:18.000000000 -0500
+++ egcc-CVS20031230/gcc/bt-load.c	2004-01-01 13:16:17.054717000 -0500
@@ -1200,7 +1200,7 @@ migrate_btr_def (btr_def def, int min_co
   bitmap_copy (live_range, def->live_range);
 
 #ifdef INSN_SCHEDULING
-  if ((*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     def_latency = insn_default_latency (def->insn);
   else
     def_latency = result_ready_cost (def->insn);
@@ -1345,12 +1345,12 @@ migrate_btr_defs (enum reg_class btr_cla
 void
 branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen)
 {
-  enum reg_class class = (*targetm.branch_target_register_class) ();
+  enum reg_class class = TARGET_BRANCH_TARGET_REGISTER_CLASS ();
   if (class != NO_REGS)
     {
       /* Initialize issue_rate.  */
-      if (targetm.sched.issue_rate)
-	issue_rate = (*targetm.sched.issue_rate) ();
+      if (1)
+	issue_rate = TARGET_SCHED_ISSUE_RATE ();
       else
 	issue_rate = 1;
 
@@ -1366,7 +1366,7 @@ branch_target_load_optimize (rtx insns, 
       /* Dominator info is also needed for migrate_btr_def.  */
       calculate_dominance_info (CDI_DOMINATORS);
       migrate_btr_defs (class,
-		       ((*targetm.branch_target_register_callee_saved)
+		       (TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED
 			(after_prologue_epilogue_gen)));
 
       free_dominance_info (CDI_DOMINATORS);
diff -rup orig/egcc-CVS20031230/gcc/builtins.c egcc-CVS20031230/gcc/builtins.c
--- orig/egcc-CVS20031230/gcc/builtins.c	2003-12-30 20:01:19.000000000 -0500
+++ egcc-CVS20031230/gcc/builtins.c	2004-01-01 13:19:20.021570000 -0500
@@ -924,7 +924,7 @@ apply_args_size (void)
 
       /* The second value is the structure value address unless this is
 	 passed as an "invisible" first argument.  */
-      if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
+      if (TARGET_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
 	size += GET_MODE_SIZE (Pmode);
 
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -1099,7 +1099,7 @@ expand_builtin_apply_args_1 (void)
   rtx registers, tem;
   int size, align, regno;
   enum machine_mode mode;
-  rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
+  rtx struct_incoming_value = TARGET_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
 
   /* Create a block where the arg-pointer, structure value address,
      and argument registers can be saved.  */
@@ -1107,7 +1107,7 @@ expand_builtin_apply_args_1 (void)
 
   /* Walk past the arg-pointer and structure value address.  */
   size = GET_MODE_SIZE (Pmode);
-  if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
+  if (TARGET_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
     size += GET_MODE_SIZE (Pmode);
 
   /* Save each register used in calling a function to the block.  */
@@ -1198,7 +1198,7 @@ expand_builtin_apply (rtx function, rtx 
   rtx incoming_args, result, reg, dest, src, call_insn;
   rtx old_stack_level = 0;
   rtx call_fusage = 0;
-  rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
+  rtx struct_value = TARGET_STRUCT_VALUE_RTX (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
 
   arguments = convert_memory_address (Pmode, arguments);
 
@@ -3789,7 +3789,7 @@ expand_builtin_saveregs (void)
   start_sequence ();
 
   /* Do whatever the machine needs done in this case.  */
-  val = targetm.calls.expand_builtin_saveregs ();
+  val = TARGET_EXPAND_BUILTIN_SAVEREGS ();
 
   seq = get_insns ();
   end_sequence ();
@@ -4931,7 +4931,7 @@ expand_builtin (tree exp, rtx target, rt
   emit_queue ();
 
   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
-    return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
+    return TARGET_EXPAND_BUILTIN (exp, target, subtarget, mode, ignore);
 
   /* When not optimizing, generate calls to library functions for a certain
      set of builtins.  */
diff -rup orig/egcc-CVS20031230/gcc/c-common.c egcc-CVS20031230/gcc/c-common.c
--- orig/egcc-CVS20031230/gcc/c-common.c	2003-12-25 20:01:09.000000000 -0500
+++ egcc-CVS20031230/gcc/c-common.c	2004-01-01 13:21:44.861263000 -0500
@@ -3467,7 +3467,7 @@ c_common_nodes_and_builtins (void)
 #include "builtins.def"
 #undef DEF_BUILTIN
 
-  (*targetm.init_builtins) ();
+  TARGET_INIT_BUILTINS ();
 
   main_identifier_node = get_identifier ("main");
 }
@@ -4695,7 +4695,7 @@ handle_mode_attribute (tree *node, tree 
 	error ("no data type for mode `%s'", p);
       else if ((TREE_CODE (type) == POINTER_TYPE
 		|| TREE_CODE (type) == REFERENCE_TYPE)
-	       && !(*targetm.valid_pointer_mode) (mode))
+	       && ! TARGET_VALID_POINTER_MODE (mode))
 	error ("invalid pointer mode `%s'", p);
       else
 	{
@@ -4737,7 +4737,7 @@ handle_section_attribute (tree *node, tr
 {
   tree decl = *node;
 
-  if (targetm.have_named_sections)
+  if (TARGET_HAVE_NAMED_SECTIONS)
     {
       if ((TREE_CODE (decl) == FUNCTION_DECL
 	   || TREE_CODE (decl) == VAR_DECL)
diff -rup orig/egcc-CVS20031230/gcc/c-decl.c egcc-CVS20031230/gcc/c-decl.c
--- orig/egcc-CVS20031230/gcc/c-decl.c	2003-12-22 20:01:24.000000000 -0500
+++ egcc-CVS20031230/gcc/c-decl.c	2004-01-01 13:26:23.850561000 -0500
@@ -854,7 +854,7 @@ duplicate_decls (tree newdecl, tree oldd
 	}
 
       DECL_ATTRIBUTES (newdecl)
-	= (*targetm.merge_decl_attributes) (olddecl, newdecl);
+	= TARGET_MERGE_DECL_ATTRIBUTES (olddecl, newdecl);
     }
 
   if (TREE_CODE (newtype) == ERROR_MARK
@@ -2694,7 +2694,7 @@ start_decl (tree declarator, tree declsp
   decl_attributes (&decl, attributes, 0);
 
   if (TREE_CODE (decl) == FUNCTION_DECL
-      && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
+      && TARGET_PROMOTE_PROTOTYPES (TREE_TYPE (decl)))
     {
       tree ce = declarator;
 
@@ -4514,7 +4514,7 @@ grokdeclarator (tree declarator, tree de
 
 	if (specbits & 1 << (int) RID_THREAD)
 	  {
-	    if (targetm.have_tls)
+	    if (TARGET_HAVE_TLS)
 	      DECL_THREAD_LOCAL (decl) = 1;
 	    else
 	      /* A mere warning is sure to result in improper semantics
@@ -5923,7 +5923,7 @@ store_parm_decls_oldstyle (void)
 		     useful for argument types like uid_t.  */
 		  DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
 
-		  if (targetm.calls.promote_prototypes (TREE_TYPE (current_function_decl))
+		  if (TARGET_PROMOTE_PROTOTYPES (TREE_TYPE (current_function_decl))
 		      && INTEGRAL_TYPE_P (TREE_TYPE (parm))
 		      && TYPE_PRECISION (TREE_TYPE (parm))
 		      < TYPE_PRECISION (integer_type_node))
@@ -6076,7 +6076,7 @@ finish_function (void)
     }
 
   if (TREE_CODE (fndecl) == FUNCTION_DECL
-      && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
+      && TARGET_PROMOTE_PROTOTYPES (TREE_TYPE (fndecl)))
     {
       tree args = DECL_ARGUMENTS (fndecl);
       for (; args; args = TREE_CHAIN (args))
@@ -6203,8 +6203,8 @@ c_expand_body_1 (tree fndecl, int nested
 
   if (DECL_STATIC_CONSTRUCTOR (fndecl))
     {
-      if (targetm.have_ctors_dtors)
-	(* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
+      if (TARGET_HAVE_CTORS_DTORS)
+	TARGET_ASM_CONSTRUCTOR (XEXP (DECL_RTL (fndecl), 0),
 				         DEFAULT_INIT_PRIORITY);
       else
 	static_ctors = tree_cons (NULL_TREE, fndecl, static_ctors);
@@ -6212,8 +6212,8 @@ c_expand_body_1 (tree fndecl, int nested
 
   if (DECL_STATIC_DESTRUCTOR (fndecl))
     {
-      if (targetm.have_ctors_dtors)
-	(* targetm.asm_out.destructor) (XEXP (DECL_RTL (fndecl), 0),
+      if (TARGET_HAVE_CTORS_DTORS)
+	TARGET_ASM_DESTRUCTOR (XEXP (DECL_RTL (fndecl), 0),
 				        DEFAULT_INIT_PRIORITY);
       else
 	static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
diff -rup orig/egcc-CVS20031230/gcc/c-objc-common.c egcc-CVS20031230/gcc/c-objc-common.c
--- orig/egcc-CVS20031230/gcc/c-objc-common.c	2003-10-31 20:01:13.000000000 -0500
+++ egcc-CVS20031230/gcc/c-objc-common.c	2004-01-01 15:41:58.422407000 -0500
@@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - S
 #include "langhooks.h"
 #include "target.h"
 #include "cgraph.h"
+#include "output.h"
 
 static bool c_tree_printer (pretty_printer *, text_info *);
 static tree start_cdtor (int);
@@ -85,7 +86,7 @@ c_cannot_inline_tree_fn (tree *fnp)
 
   /* Don't auto-inline anything that might not be bound within
      this unit of translation.  */
-  if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
+  if (!DECL_DECLARED_INLINE_P (fn) && ! TARGET_BINDS_LOCAL_P (fn))
     {
       if (do_warning)
 	warning ("%Jfunction '%F' can never be inlined because it might not "
diff -rup orig/egcc-CVS20031230/gcc/c-pch.c egcc-CVS20031230/gcc/c-pch.c
--- orig/egcc-CVS20031230/gcc/c-pch.c	2003-12-17 20:02:10.000000000 -0500
+++ egcc-CVS20031230/gcc/c-pch.c	2004-01-01 13:29:00.459668000 -0500
@@ -121,7 +121,7 @@ pch_init (void)
   v.version_length = strlen (version_string);
   v.debug_info_type = write_symbols;
   v.pch_init = &pch_init;
-  target_validity = targetm.get_pch_validity (&v.target_data_length);
+  target_validity = TARGET_GET_PCH_VALIDITY (&v.target_data_length);
   
   if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
       || fwrite (&v, sizeof (v), 1, f) != 1
@@ -322,7 +322,7 @@ c_common_valid_pch (cpp_reader *pfile, c
     if ((size_t) read (fd, this_file_data, v.target_data_length)
 	!= v.target_data_length)
       fatal_error ("can't read %s: %m", name);
-    msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
+    msg = TARGET_PCH_VALID_P (this_file_data, v.target_data_length);
     free (this_file_data);
     if (msg != NULL)
       {
diff -rup orig/egcc-CVS20031230/gcc/c-typeck.c egcc-CVS20031230/gcc/c-typeck.c
--- orig/egcc-CVS20031230/gcc/c-typeck.c	2003-12-23 20:01:57.000000000 -0500
+++ egcc-CVS20031230/gcc/c-typeck.c	2004-01-01 13:37:20.466140000 -0500
@@ -227,7 +227,7 @@ common_type (tree t1, tree t2)
     return t1;
 
   /* Merge the attributes.  */
-  attributes = (*targetm.merge_type_attributes) (t1, t2);
+  attributes = TARGET_MERGE_TYPE_ATTRIBUTES (t1, t2);
 
   /* Treat an enum type as the unsigned integer type of the same width.  */
 
@@ -502,7 +502,7 @@ comptypes (tree type1, tree type2, int f
     return 1;
 
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
-  if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
+  if (! (attrval = TARGET_COMP_TYPE_ATTRIBUTES (t1, t2)))
      return 0;
 
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
@@ -577,8 +577,8 @@ comptypes (tree type1, tree type2, int f
 
     case VECTOR_TYPE:
       /* The target might allow certain vector types to be compatible.  */
-      val = (*targetm.vector_opaque_p) (t1)
-	|| (*targetm.vector_opaque_p) (t2);
+      val = TARGET_VECTOR_OPAQUE_P (t1)
+	|| TARGET_VECTOR_OPAQUE_P (t2);
       break;
 
     default:
@@ -1914,7 +1914,7 @@ convert_arguments (tree typelist, tree v
 					        (char *) 0, /* arg passing  */
 						fundecl, name, parmnum + 1);
 
-	      if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
+	      if (TARGET_PROMOTE_PROTOTYPES (fundecl ? TREE_TYPE (fundecl) : 0)
 		  && INTEGRAL_TYPE_P (type)
 		  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
 		parmval = default_conversion (parmval);
@@ -3418,8 +3418,8 @@ convert_for_assignment (tree type, tree 
     }
   /* Some types can interconvert without explicit casts.  */
   else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
-	   && ((*targetm.vector_opaque_p) (type)
-	       || (*targetm.vector_opaque_p) (rhstype)))
+	   && (TARGET_VECTOR_OPAQUE_P (type)
+	       || TARGET_VECTOR_OPAQUE_P (rhstype)))
     return convert (type, rhs);
   /* Arithmetic types all interconvert, and enum is treated like int.  */
   else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
@@ -3533,8 +3533,8 @@ convert_for_assignment (tree type, tree 
       int target_cmp = 0;   /* Cache comp_target_types () result.  */
 
       /* Opaque pointers are treated like void pointers.  */
-      is_opaque_pointer = ((*targetm.vector_opaque_p) (type)
-                           || (*targetm.vector_opaque_p) (rhstype))
+      is_opaque_pointer = (TARGET_VECTOR_OPAQUE_P (type)
+                           || TARGET_VECTOR_OPAQUE_P (rhstype))
         && TREE_CODE (ttl) == VECTOR_TYPE
         && TREE_CODE (ttr) == VECTOR_TYPE;
 
@@ -3663,7 +3663,7 @@ c_convert_parm_for_inlining (tree parm, 
   ret = convert_for_assignment (type, value,
 				(char *) 0 /* arg passing  */, fn,
 				DECL_NAME (fn), argnum);
-  if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
+  if (TARGET_PROMOTE_PROTOTYPES (TREE_TYPE (fn))
       && INTEGRAL_TYPE_P (type)
       && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
     ret = default_conversion (ret);
@@ -4480,7 +4480,7 @@ really_start_incremental_init (tree type
   if (type == 0)
     type = TREE_TYPE (constructor_decl);
 
-  if ((*targetm.vector_opaque_p) (type))
+  if (TARGET_VECTOR_OPAQUE_P (type))
     error ("opaque vector types cannot be initialized");
 
   p->type = constructor_type;
diff -rup orig/egcc-CVS20031230/gcc/calls.c egcc-CVS20031230/gcc/calls.c
--- orig/egcc-CVS20031230/gcc/calls.c	2003-12-24 20:02:08.000000000 -0500
+++ egcc-CVS20031230/gcc/calls.c	2004-01-01 13:40:15.634290000 -0500
@@ -1192,7 +1192,7 @@ initialize_argument_information (int num
       mode = TYPE_MODE (type);
       unsignedp = TREE_UNSIGNED (type);
 
-      if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0))
+      if (TARGET_PROMOTE_FUNCTION_ARGS (fndecl ? TREE_TYPE (fndecl) : 0))
 	mode = promote_mode (type, mode, &unsignedp, 1);
 
       args[i].unsignedp = unsignedp;
@@ -2030,7 +2030,7 @@ fix_unsafe_tree (tree t)
 static bool
 shift_returned_value (tree type, rtx *value)
 {
-  if (targetm.calls.return_in_msb (type))
+  if (TARGET_RETURN_IN_MSB (type))
     {
       HOST_WIDE_INT shift;
 
@@ -2226,7 +2226,7 @@ expand_call (tree exp, rtx target, int i
       flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
     }
 
-  struct_value = targetm.calls.struct_value_rtx (fndecl ? TREE_TYPE (fndecl) : 0, 0);
+  struct_value = TARGET_STRUCT_VALUE_RTX (fndecl ? TREE_TYPE (fndecl) : 0, 0);
 
   /* Warn if this value is an aggregate type,
      regardless of which calling convention we are using for it.  */
@@ -2409,24 +2409,24 @@ expand_call (tree exp, rtx target, int i
      (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
+     If TARGET_PRETEND_OUTGOING_VARARGS_NAMED() returns
      nonzero, and STRICT_ARGUMENT_NAMING is 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 TARGET_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 ((targetm.calls.strict_argument_naming (&args_so_far)
-       || ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
+  if ((TARGET_STRICT_ARGUMENT_NAMING (&args_so_far)
+       || ! TARGET_PRETEND_OUTGOING_VARARGS_NAMED (&args_so_far))
       && type_arg_types != 0)
     n_named_args
       = (list_length (type_arg_types)
 	 /* Don't include the last named arg.  */
-	 - (targetm.calls.strict_argument_naming (&args_so_far) ? 0 : 1)
+	 - (TARGET_STRICT_ARGUMENT_NAMING (&args_so_far) ? 0 : 1)
 	 /* Count the struct value address, if it is passed as a parm.  */
 	 + structure_value_addr_parm);
   else
@@ -2516,7 +2516,7 @@ expand_call (tree exp, rtx target, int i
       || structure_value_addr != NULL_RTX
       /* Check whether the target is able to optimize the call
 	 into a sibcall.  */
-      || !(*targetm.function_ok_for_sibcall) (fndecl, exp)
+      || ! TARGET_FUNCTION_OK_FOR_SIBCALL (fndecl, exp)
       /* Functions that do not return exactly once may not be sibcall
          optimized.  */
       || (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
@@ -3335,7 +3335,7 @@ expand_call (tree exp, rtx target, int i
 	  target = copy_to_reg (valreg);
 	}
 
-      if (targetm.calls.promote_function_return(funtype))
+      if (TARGET_PROMOTE_FUNCTION_RETURN(funtype))
 	{
       /* If we promoted this return value, make the proper SUBREG.  TARGET
 	 might be const0_rtx here, so be careful.  */
@@ -3676,7 +3676,7 @@ emit_library_call_value_1 (int retval, r
   int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
   char *initial_stack_usage_map = stack_usage_map;
 
-  rtx struct_value = targetm.calls.struct_value_rtx (0, 0);
+  rtx struct_value = TARGET_STRUCT_VALUE_RTX (0, 0);
 
 #ifdef REG_PARM_STACK_SPACE
 #ifdef MAYBE_REG_PARM_STACK_SPACE
diff -rup orig/egcc-CVS20031230/gcc/cfgcleanup.c egcc-CVS20031230/gcc/cfgcleanup.c
--- orig/egcc-CVS20031230/gcc/cfgcleanup.c	2003-12-13 20:01:16.000000000 -0500
+++ egcc-CVS20031230/gcc/cfgcleanup.c	2004-01-01 13:43:04.730734000 -0500
@@ -1675,7 +1675,7 @@ try_optimize_cfg (int mode)
   if (mode & CLEANUP_UPDATE_LIFE)
     clear_bb_flags ();
 
-  if (! (* targetm.cannot_modify_jumps_p) ())
+  if (! TARGET_CANNOT_MODIFY_JUMPS_P ())
     {
       /* Attempt to merge blocks as made possible by edge removal.  If
 	 a block has only one successor, and the successor has only
diff -rup orig/egcc-CVS20031230/gcc/cfglayout.c egcc-CVS20031230/gcc/cfglayout.c
--- orig/egcc-CVS20031230/gcc/cfglayout.c	2003-12-30 20:01:19.000000000 -0500
+++ egcc-CVS20031230/gcc/cfglayout.c	2004-01-01 13:45:46.958240000 -0500
@@ -900,7 +900,7 @@ cfg_layout_can_duplicate_bb_p (basic_blo
     return false;
 
   /* Do not duplicate blocks containing insns that can't be copied.  */
-  if (targetm.cannot_copy_insn_p)
+  if (TARGET_CANNOT_COPY_INSN_P)
     {
       rtx insn = BB_HEAD (bb);
       while (1)
diff -rup orig/egcc-CVS20031230/gcc/combine.c egcc-CVS20031230/gcc/combine.c
--- orig/egcc-CVS20031230/gcc/combine.c	2003-12-16 20:01:14.000000000 -0500
+++ egcc-CVS20031230/gcc/combine.c	2004-01-01 13:46:23.175817000 -0500
@@ -806,7 +806,7 @@ setup_incoming_promotions (void)
   int unsignedp;
   rtx first = get_insns ();
 
-  if (targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
+  if (TARGET_PROMOTE_FUNCTION_ARGS (TREE_TYPE (cfun->decl)))
     {
 #ifndef OUTGOING_REGNO
 #define OUTGOING_REGNO(N) N
diff -rup orig/egcc-CVS20031230/gcc/config/dbxcoff.h egcc-CVS20031230/gcc/config/dbxcoff.h
--- orig/egcc-CVS20031230/gcc/config/dbxcoff.h	2003-09-27 20:00:54.000000000 -0400
+++ egcc-CVS20031230/gcc/config/dbxcoff.h	2004-01-01 15:20:52.476904000 -0500
@@ -69,7 +69,7 @@ Boston, MA 02111-1307, USA.  */
     assemble_name (FILE,					\
 		   XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
     putc ('\n', FILE);						\
-    (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER);	\
+    TARGET_ASM_INTERNAL_LABEL (FILE, "LM", COUNTER);	\
   } }
 
 /* When generating stabs debugging, use N_BINCL entries.  */
diff -rup orig/egcc-CVS20031230/gcc/config/dbxelf.h egcc-CVS20031230/gcc/config/dbxelf.h
--- orig/egcc-CVS20031230/gcc/config/dbxelf.h	2003-09-27 20:00:54.000000000 -0400
+++ egcc-CVS20031230/gcc/config/dbxelf.h	2004-01-01 15:19:56.751645000 -0500
@@ -68,7 +68,7 @@ do									\
     assemble_name (FILE,						\
 		   XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
     putc ('\n', FILE);							\
-    (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER);		\
+    TARGET_ASM_INTERNAL_LABEL (FILE, "LM", COUNTER);		\
   }									\
 while (0)
 
diff -rup orig/egcc-CVS20031230/gcc/config/elfos.h egcc-CVS20031230/gcc/config/elfos.h
--- orig/egcc-CVS20031230/gcc/config/elfos.h	2003-12-23 20:02:07.000000000 -0500
+++ egcc-CVS20031230/gcc/config/elfos.h	2004-01-01 15:20:27.669086000 -0500
@@ -143,7 +143,7 @@ Boston, MA 02111-1307, USA.  */
   do									\
     {									\
       ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE)	\
-	(*targetm.asm_out.internal_label) (FILE, PREFIX, NUM);			\
+	TARGET_ASM_INTERNAL_LABEL (FILE, PREFIX, NUM);			\
     }									\
   while (0)
 
@@ -152,7 +152,7 @@ Boston, MA 02111-1307, USA.  */
    in each assembly file where they are referenced.  */
 
 #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN)	\
-  (*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0))
+  TARGET_ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0))
 
 /* This says how to output assembler code to declare an
    uninitialized external linkage data object.  Under SVR4,
diff -rup orig/egcc-CVS20031230/gcc/config/sparc/redef.h egcc-CVS20031230/gcc/config/sparc/redef.h
--- orig/egcc-CVS20031230/gcc/config/sparc/redef.h	2003-12-31 10:18:03.175599000 -0500
+++ egcc-CVS20031230/gcc/config/sparc/redef.h	2003-12-31 10:17:45.137185000 -0500
@@ -0,0 +1,60 @@
+/* Initialize the GCC target structure.  */
+
+/* The sparc default is to use .half rather than .short for aligned
+   HI objects.  Use .word instead of .long on non-ELF systems.  */
+#undef TARGET_ASM_ALIGNED_HI_OP
+#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
+#ifndef OBJECT_FORMAT_ELF
+#undef TARGET_ASM_ALIGNED_SI_OP
+#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
+#endif
+
+#undef TARGET_ASM_UNALIGNED_HI_OP
+#define TARGET_ASM_UNALIGNED_HI_OP "\t.uahalf\t"
+#undef TARGET_ASM_UNALIGNED_SI_OP
+#define TARGET_ASM_UNALIGNED_SI_OP "\t.uaword\t"
+#undef TARGET_ASM_UNALIGNED_DI_OP
+#define TARGET_ASM_UNALIGNED_DI_OP "\t.uaxword\t"
+
+/* The target hook has to handle DI-mode values.  */
+#undef TARGET_ASM_INTEGER
+#define TARGET_ASM_INTEGER sparc_assemble_integer
+
+#undef TARGET_ASM_FUNCTION_PROLOGUE
+#define TARGET_ASM_FUNCTION_PROLOGUE sparc_output_function_prologue
+#undef TARGET_ASM_FUNCTION_EPILOGUE
+#define TARGET_ASM_FUNCTION_EPILOGUE sparc_output_function_epilogue
+
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST sparc_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE sparc_issue_rate
+#undef TARGET_SCHED_INIT
+#define TARGET_SCHED_INIT sparc_sched_init
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE sparc_use_dfa_pipeline_interface
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs
+
+#ifdef HAVE_AS_TLS
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS true
+#endif
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM sparc_cannot_force_const_mem
+
+#undef TARGET_ASM_OUTPUT_MI_THUNK
+#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS sparc_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
diff -rup orig/egcc-CVS20031230/gcc/config/sparc/sparc-protos.h egcc-CVS20031230/gcc/config/sparc/sparc-protos.h
--- orig/egcc-CVS20031230/gcc/config/sparc/sparc-protos.h	2003-11-26 08:47:32.000000000 -0500
+++ egcc-CVS20031230/gcc/config/sparc/sparc-protos.h	2004-01-01 15:06:18.982972000 -0500
@@ -123,4 +123,21 @@ extern int sparc_extra_constraint_check 
 extern void sparc_output_dwarf_dtprel (FILE*, int, rtx);
 #endif /* RTX_CODE */
 
+#ifdef OBJECT_FORMAT_ELF
+extern void sparc_elf_asm_named_section (const char *, unsigned int);
+#endif
+extern bool sparc_assemble_integer (rtx, unsigned int, int);
+extern bool sparc_cannot_force_const_mem (rtx);
+extern int sparc_use_dfa_pipeline_interface (void);
+extern int sparc_issue_rate (void);
+extern bool sparc_function_ok_for_sibcall (tree, tree);
+extern bool sparc_rtx_costs (rtx, int, int, int *);
+extern void sparc_output_function_prologue (FILE *, HOST_WIDE_INT);
+extern void sparc_output_function_epilogue (FILE *, HOST_WIDE_INT);
+extern int sparc_use_sched_lookahead (void);
+extern int sparc_adjust_cost (rtx, rtx, rtx, int);
+extern void sparc_sched_init (FILE *, int, int);
+extern void sparc_init_libfuncs (void);
+extern void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+				   HOST_WIDE_INT, tree);
 #endif /* __SPARC_PROTOS_H__ */
diff -rup orig/egcc-CVS20031230/gcc/config/sparc/sparc.c egcc-CVS20031230/gcc/config/sparc/sparc.c
--- orig/egcc-CVS20031230/gcc/config/sparc/sparc.c	2003-12-10 20:01:40.000000000 -0500
+++ egcc-CVS20031230/gcc/config/sparc/sparc.c	2004-01-01 15:06:21.452654000 -0500
@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA.  */
 #include "tm_p.h"
 #include "debug.h"
 #include "target.h"
-#include "target-def.h"
 #include "cfglayout.h"
 
 /* 1 if the caller has placed an "unimp" insn immediately after the call.
@@ -148,11 +147,8 @@ static void sparc_output_addr_diff_vec (
 static void sparc_output_deferred_case_vectors (void);
 static int check_return_regs (rtx);
 static int epilogue_renumber (rtx *, int);
-static bool sparc_assemble_integer (rtx, unsigned int, int);
 static int set_extends (rtx);
 static void output_restore_regs (FILE *, int);
-static void sparc_output_function_prologue (FILE *, HOST_WIDE_INT);
-static void sparc_output_function_epilogue (FILE *, HOST_WIDE_INT);
 static void sparc_flat_function_epilogue (FILE *, HOST_WIDE_INT);
 static void sparc_flat_function_prologue (FILE *, HOST_WIDE_INT);
 static void sparc_flat_save_restore (FILE *, const char *, int,
@@ -161,20 +157,12 @@ static void sparc_flat_save_restore (FIL
 				     HOST_WIDE_INT);
 static void sparc_nonflat_function_epilogue (FILE *, HOST_WIDE_INT, int);
 static void sparc_nonflat_function_prologue (FILE *, HOST_WIDE_INT, int);
-#ifdef OBJECT_FORMAT_ELF
-static void sparc_elf_asm_named_section (const char *, unsigned int);
-#endif
 static void sparc_aout_select_section (tree, int, unsigned HOST_WIDE_INT)
      ATTRIBUTE_UNUSED;
 static void sparc_aout_select_rtx_section (enum machine_mode, rtx,
 					   unsigned HOST_WIDE_INT)
      ATTRIBUTE_UNUSED;
 
-static int sparc_adjust_cost (rtx, rtx, rtx, int);
-static int sparc_issue_rate (void);
-static void sparc_sched_init (FILE *, int, int);
-static int sparc_use_dfa_pipeline_interface (void);
-static int sparc_use_sched_lookahead (void);
 
 static void emit_soft_tfmode_libcall (const char *, int, rtx *);
 static void emit_soft_tfmode_binop (enum rtx_code, rtx *);
@@ -182,17 +170,11 @@ static void emit_soft_tfmode_unop (enum 
 static void emit_soft_tfmode_cvt (enum rtx_code, rtx *);
 static void emit_hard_tfmode_operation (enum rtx_code, rtx *);
 
-static bool sparc_function_ok_for_sibcall (tree, tree);
-static void sparc_init_libfuncs (void);
-static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
-				   HOST_WIDE_INT, tree);
 static struct machine_function * sparc_init_machine_status (void);
-static bool sparc_cannot_force_const_mem (rtx);
 static rtx sparc_tls_get_addr (void);
 static rtx sparc_tls_got (void);
 static const char *get_some_local_dynamic_name (void);
 static int get_some_local_dynamic_name_1 (rtx *, void *);
-static bool sparc_rtx_costs (rtx, int, int, int *);
 \f
 /* Option handling.  */
 
@@ -215,66 +197,6 @@ struct sparc_cpu_select sparc_select[] =
 /* CPU type.  This is set from TARGET_CPU_DEFAULT and -m{cpu,tune}=xxx.  */
 enum processor_type sparc_cpu;
 \f
-/* Initialize the GCC target structure.  */
-
-/* The sparc default is to use .half rather than .short for aligned
-   HI objects.  Use .word instead of .long on non-ELF systems.  */
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
-#ifndef OBJECT_FORMAT_ELF
-#undef TARGET_ASM_ALIGNED_SI_OP
-#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
-#endif
-
-#undef TARGET_ASM_UNALIGNED_HI_OP
-#define TARGET_ASM_UNALIGNED_HI_OP "\t.uahalf\t"
-#undef TARGET_ASM_UNALIGNED_SI_OP
-#define TARGET_ASM_UNALIGNED_SI_OP "\t.uaword\t"
-#undef TARGET_ASM_UNALIGNED_DI_OP
-#define TARGET_ASM_UNALIGNED_DI_OP "\t.uaxword\t"
-
-/* The target hook has to handle DI-mode values.  */
-#undef TARGET_ASM_INTEGER
-#define TARGET_ASM_INTEGER sparc_assemble_integer
-
-#undef TARGET_ASM_FUNCTION_PROLOGUE
-#define TARGET_ASM_FUNCTION_PROLOGUE sparc_output_function_prologue
-#undef TARGET_ASM_FUNCTION_EPILOGUE
-#define TARGET_ASM_FUNCTION_EPILOGUE sparc_output_function_epilogue
-
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST sparc_adjust_cost
-#undef TARGET_SCHED_ISSUE_RATE
-#define TARGET_SCHED_ISSUE_RATE sparc_issue_rate
-#undef TARGET_SCHED_INIT
-#define TARGET_SCHED_INIT sparc_sched_init
-#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
-#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE sparc_use_dfa_pipeline_interface
-#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
-#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead
-
-#undef TARGET_FUNCTION_OK_FOR_SIBCALL
-#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall
-
-#undef TARGET_INIT_LIBFUNCS
-#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs
-
-#ifdef HAVE_AS_TLS
-#undef TARGET_HAVE_TLS
-#define TARGET_HAVE_TLS true
-#endif
-#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM sparc_cannot_force_const_mem
-
-#undef TARGET_ASM_OUTPUT_MI_THUNK
-#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
-#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
-
-#undef TARGET_RTX_COSTS
-#define TARGET_RTX_COSTS sparc_rtx_costs
-#undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST hook_int_rtx_0
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
@@ -3063,7 +2985,7 @@ reg_unused_after (rtx reg, rtx insn)
    is not possible if X contains the address of a symbol that is
    not constant (TLS) or not known at final link time (PIC).  */
 
-static bool
+bool
 sparc_cannot_force_const_mem (rtx x)
 {
   switch (GET_CODE (x))
@@ -3703,7 +3625,7 @@ load_pic_register (void)
       align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
       if (align > 0)
 	ASM_OUTPUT_ALIGN (asm_out_file, align);
-      (*targetm.asm_out.internal_label) (asm_out_file, "LGETPC", 0);
+      TARGET_ASM_INTERNAL_LABEL (asm_out_file, "LGETPC", 0);
       fputs ("\tretl\n\tadd\t%o7, %l7, %l7\n", asm_out_file);
     }
 
@@ -4294,7 +4216,7 @@ sparc_output_scratch_registers (FILE *fi
    to do a "save" insn.  The decision about whether or not
    to do this is made in regclass.c.  */
 
-static void
+void
 sparc_output_function_prologue (FILE *file, HOST_WIDE_INT size)
 {
   if (TARGET_FLAT)
@@ -4459,7 +4381,7 @@ output_restore_regs (FILE *file, int lea
    of alloca; we also take advantage of it to omit stack adjustments
    before returning.  */
 
-static void
+void
 sparc_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
 {
   if (TARGET_FLAT)
@@ -6974,7 +6896,7 @@ print_operand (FILE *file, rtx x, int co
 /* Target hook for assembling integer objects.  The sparc version has
    special handling for aligned DI-mode objects.  */
 
-static bool
+bool
 sparc_assemble_integer (rtx x, unsigned int size, int aligned_p)
 {
   /* ??? We only output .xword's for symbols and only then in environments
@@ -8113,7 +8035,7 @@ hypersparc_adjust_cost (rtx insn, rtx li
   return cost;
 }
 
-static int
+int
 sparc_adjust_cost(rtx insn, rtx link, rtx dep, int cost)
 {
   switch (sparc_cpu)
@@ -8131,14 +8053,14 @@ sparc_adjust_cost(rtx insn, rtx link, rt
   return cost;
 }
 
-static void
+void
 sparc_sched_init (FILE *dump ATTRIBUTE_UNUSED,
 		  int sched_verbose ATTRIBUTE_UNUSED,
 		  int max_ready ATTRIBUTE_UNUSED)
 {
 }
   
-static int
+int
 sparc_use_dfa_pipeline_interface (void)
 {
   if ((1 << sparc_cpu) &
@@ -8150,7 +8072,7 @@ sparc_use_dfa_pipeline_interface (void)
   return 0;
 }
 
-static int
+int
 sparc_use_sched_lookahead (void)
 {
   if (sparc_cpu == PROCESSOR_ULTRASPARC
@@ -8163,7 +8085,7 @@ sparc_use_sched_lookahead (void)
   return 0;
 }
 
-static int
+int
 sparc_issue_rate (void)
 {
   switch (sparc_cpu)
@@ -8276,7 +8198,7 @@ sparc_output_addr_vec (rtx vec)
   ASM_OUTPUT_CASE_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab),
 			 NEXT_INSN (lab));
 #else
-  (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+  TARGET_ASM_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
 #endif
 
   for (idx = 0; idx < vlen; idx++)
@@ -8305,7 +8227,7 @@ sparc_output_addr_diff_vec (rtx vec)
   ASM_OUTPUT_CASE_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab),
 			 NEXT_INSN (lab));
 #else
-  (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+  TARGET_ASM_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
 #endif
 
   for (idx = 0; idx < vlen; idx++)
@@ -8461,7 +8383,7 @@ sparc_profile_hook (int labelno)
 }
 \f
 #ifdef OBJECT_FORMAT_ELF
-static void
+void
 sparc_elf_asm_named_section (const char *name, unsigned int flags)
 {
   if (flags & SECTION_MERGE)
@@ -8503,7 +8425,7 @@ sparc_elf_asm_named_section (const char 
    the pointer to the struct return area to a constructor (which returns
    void) and then nothing else happens.  Such a sibling call would look
    valid without the added check here.  */
-static bool
+bool
 sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
 {
   return (decl
@@ -8514,7 +8436,7 @@ sparc_function_ok_for_sibcall (tree decl
 /* libfunc renaming.  */
 #include "config/gofast.h"
 
-static void
+void
 sparc_init_libfuncs (void)
 {
   if (TARGET_ARCH32)
@@ -8689,7 +8611,7 @@ sparc_extra_constraint_check (rtx op, in
    ??? scheduler description.  Some day, teach genautomata to output
    ??? the latencies and then CSE will just use that.  */
 
-static bool
+bool
 sparc_rtx_costs (rtx x, int code, int outer_code, int *total)
 {
   switch (code)
@@ -9057,7 +8979,7 @@ sparc_rtx_costs (rtx x, int code, int ou
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
 
-static void
+void
 sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
 		       HOST_WIDE_INT delta,
 		       HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
diff -rup orig/egcc-CVS20031230/gcc/config/sparc/sysv4.h egcc-CVS20031230/gcc/config/sparc/sysv4.h
--- orig/egcc-CVS20031230/gcc/config/sparc/sysv4.h	2003-06-17 10:12:11.000000000 -0400
+++ egcc-CVS20031230/gcc/config/sparc/sysv4.h	2004-01-01 15:05:00.329337000 -0500
@@ -86,7 +86,7 @@ Boston, MA 02111-1307, USA.  */
 #undef ASM_OUTPUT_CASE_LABEL
 #define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE)		\
 do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3);		\
-     (*targetm.asm_out.internal_label) ((FILE), PREFIX, NUM);		\
+     TARGET_ASM_INTERNAL_LABEL ((FILE), PREFIX, NUM);		\
    } while (0)
 
 /* This is how to equate one symbol to another symbol.  The syntax used is
diff -rup orig/egcc-CVS20031230/gcc/coverage.c egcc-CVS20031230/gcc/coverage.c
--- orig/egcc-CVS20031230/gcc/coverage.c	2003-12-29 20:01:10.000000000 -0500
+++ egcc-CVS20031230/gcc/coverage.c	2004-01-01 13:47:14.712259000 -0500
@@ -864,7 +864,7 @@ create_coverage (void)
 
   /* It can be a static function as long as collect2 does not have
      to scan the object file to find its ctor/dtor routine.  */
-  TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
+  TREE_PUBLIC (ctor) = ! TARGET_HAVE_CTORS_DTORS;
   TREE_USED (ctor) = 1;
   DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
   DECL_UNINLINABLE (ctor) = 1;
@@ -892,8 +892,8 @@ create_coverage (void)
     fflush (asm_out_file);
   current_function_decl = NULL_TREE;
 
-  if (targetm.have_ctors_dtors)
-    (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
+  if (TARGET_HAVE_CTORS_DTORS)
+    TARGET_ASM_CONSTRUCTOR (XEXP (DECL_RTL (ctor), 0),
 				     DEFAULT_INIT_PRIORITY);
 }
 \f
diff -rup orig/egcc-CVS20031230/gcc/cp/call.c egcc-CVS20031230/gcc/cp/call.c
--- orig/egcc-CVS20031230/gcc/cp/call.c	2003-12-29 20:01:19.000000000 -0500
+++ egcc-CVS20031230/gcc/cp/call.c	2004-01-01 14:58:25.520307000 -0500
@@ -649,8 +649,8 @@ standard_conversion (tree to, tree from,
   else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
 	   && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
 	   && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
-	   && ((*targetm.vector_opaque_p) (TREE_TYPE (to))
-	       || (*targetm.vector_opaque_p) (TREE_TYPE (from))))
+	   && (TARGET_VECTOR_OPAQUE_P (TREE_TYPE (to))
+	       || TARGET_VECTOR_OPAQUE_P (TREE_TYPE (from))))
     conv = build_conv (STD_CONV, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
 	   || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
@@ -809,8 +809,8 @@ standard_conversion (tree to, tree from,
 	ICS_STD_RANK (conv) = PROMO_RANK;
     }
   else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (from)
-	  || (*targetm.vector_opaque_p) (to)))
+      && (TARGET_VECTOR_OPAQUE_P (from)
+	  || TARGET_VECTOR_OPAQUE_P (to)))
     return build_conv (STD_CONV, to, conv);
   else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
 	   && is_properly_derived_from (from, to))
diff -rup orig/egcc-CVS20031230/gcc/cp/decl.c egcc-CVS20031230/gcc/cp/decl.c
--- orig/egcc-CVS20031230/gcc/cp/decl.c	2003-12-30 20:01:35.000000000 -0500
+++ egcc-CVS20031230/gcc/cp/decl.c	2004-01-01 14:59:23.966918000 -0500
@@ -1263,7 +1263,7 @@ duplicate_decls (tree newdecl, tree oldd
       else if (DECL_ANTICIPATED (olddecl))
 	{
 	  tree type = TREE_TYPE (newdecl);
-	  tree attribs = (*targetm.merge_type_attributes)
+	  tree attribs = TARGET_MERGE_TYPE_ATTRIBUTES
 	    (TREE_TYPE (olddecl), type);
 
 	  type = build_type_attribute_variant (type, attribs);
@@ -1577,7 +1577,7 @@ duplicate_decls (tree newdecl, tree oldd
   /* Copy all the DECL_... slots specified in the new decl
      except for any that we copy here from the old type.  */
   DECL_ATTRIBUTES (newdecl)
-    = (*targetm.merge_decl_attributes) (olddecl, newdecl);
+    = TARGET_MERGE_DECL_ATTRIBUTES (olddecl, newdecl);
 
   if (TREE_CODE (newdecl) == TEMPLATE_DECL)
     {
@@ -4459,7 +4459,7 @@ check_initializer (tree decl, tree init,
 	  if (CP_AGGREGATE_TYPE_P (type))
 	    init = reshape_init (type, &init);
 
-	  if ((*targetm.vector_opaque_p) (type))
+	  if (TARGET_VECTOR_OPAQUE_P (type))
 	    {
 	      error ("opaque vector types cannot be initialized");
 	      init = error_mark_node;
@@ -5854,7 +5854,7 @@ grokvardecl (tree type,
 
   if (RIDBIT_SETP (RID_THREAD, specbits))
     {
-      if (targetm.have_tls)
+      if (TARGET_HAVE_TLS)
 	DECL_THREAD_LOCAL (decl) = 1;
       else
 	/* A mere warning is sure to result in improper semantics
diff -rup orig/egcc-CVS20031230/gcc/cp/decl2.c egcc-CVS20031230/gcc/cp/decl2.c
--- orig/egcc-CVS20031230/gcc/cp/decl2.c	2003-12-23 20:02:23.000000000 -0500
+++ egcc-CVS20031230/gcc/cp/decl2.c	2004-01-01 15:00:43.080609000 -0500
@@ -1909,7 +1909,7 @@ start_objects (int method_type, int init
 
   /* It can be a static function as long as collect2 does not have
      to scan the object file to find its ctor/dtor routine.  */
-  TREE_PUBLIC (current_function_decl) = ! targetm.have_ctors_dtors;
+  TREE_PUBLIC (current_function_decl) = ! TARGET_HAVE_CTORS_DTORS;
 
   /* Mark this declaration as used to avoid spurious warnings.  */
   TREE_USED (current_function_decl) = 1;
@@ -1952,13 +1952,13 @@ finish_objects (int method_type, int ini
   if (flag_syntax_only)
     return;
 
-  if (targetm.have_ctors_dtors)
+  if (TARGET_HAVE_CTORS_DTORS)
     {
       rtx fnsym = XEXP (DECL_RTL (fn), 0);
       if (method_type == 'I')
-	(* targetm.asm_out.constructor) (fnsym, initp);
+	TARGET_ASM_CONSTRUCTOR (fnsym, initp);
       else
-	(* targetm.asm_out.destructor) (fnsym, initp);
+	TARGET_ASM_DESTRUCTOR (fnsym, initp);
     }
 }
 
diff -rup orig/egcc-CVS20031230/gcc/cp/method.c egcc-CVS20031230/gcc/cp/method.c
--- orig/egcc-CVS20031230/gcc/cp/method.c	2003-12-12 20:01:25.000000000 -0500
+++ egcc-CVS20031230/gcc/cp/method.c	2004-01-01 15:02:09.333460000 -0500
@@ -400,7 +400,7 @@ use_thunk (tree thunk_fndecl, bool emit_
   push_to_top_level ();
 
 #ifdef ASM_OUTPUT_DEF
-  if (targetm.have_named_sections)
+  if (TARGET_HAVE_NAMED_SECTIONS)
     {
       resolve_unique_section (function, 0, flag_function_sections);
 
@@ -420,7 +420,7 @@ use_thunk (tree thunk_fndecl, bool emit_
   BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) = DECL_ARGUMENTS (thunk_fndecl);
   
   if (this_adjusting
-      && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
+      && TARGET_ASM_CAN_OUTPUT_MI_THUNK (thunk_fndecl, fixed_offset,
 					      virtual_value, alias))
     {
       const char *fnname;
@@ -432,7 +432,7 @@ use_thunk (tree thunk_fndecl, bool emit_
       current_function_is_thunk = 1;
       assemble_start_function (thunk_fndecl, fnname);
 
-      targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
+      TARGET_ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl,
 				       fixed_offset, virtual_value, alias);
 
       assemble_end_function (thunk_fndecl, fnname);
diff -rup orig/egcc-CVS20031230/gcc/cp/tree.c egcc-CVS20031230/gcc/cp/tree.c
--- orig/egcc-CVS20031230/gcc/cp/tree.c	2003-12-30 20:01:36.000000000 -0500
+++ egcc-CVS20031230/gcc/cp/tree.c	2004-01-01 15:41:10.656158000 -0500
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "integrate.h"
 #include "tree-inline.h"
 #include "target.h"
+#include "output.h"
 
 static tree bot_manip (tree *, int *, void *);
 static tree bot_replace (tree *, int *, void *);
@@ -2057,7 +2058,7 @@ cp_cannot_inline_tree_fn (tree* fnp)
 
   /* Don't auto-inline anything that might not be bound within
      this unit of translation.  */
-  if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
+  if (!DECL_DECLARED_INLINE_P (fn) && ! TARGET_BINDS_LOCAL_P (fn))
     {
       DECL_UNINLINABLE (fn) = 1;
       return 1;
diff -rup orig/egcc-CVS20031230/gcc/cp/typeck.c egcc-CVS20031230/gcc/cp/typeck.c
--- orig/egcc-CVS20031230/gcc/cp/typeck.c	2003-12-29 20:01:21.000000000 -0500
+++ egcc-CVS20031230/gcc/cp/typeck.c	2004-01-01 15:03:44.125655000 -0500
@@ -277,7 +277,7 @@ type_after_usual_arithmetic_conversions 
   /* In what follows, we slightly generalize the rules given in [expr] so
      as to deal with `long long' and `complex'.  First, merge the
      attributes.  */
-  attributes = (*targetm.merge_type_attributes) (t1, t2);
+  attributes = TARGET_MERGE_TYPE_ATTRIBUTES (t1, t2);
 
   /* If one type is complex, form the common type of the non-complex
      components, then make that complex.  Use T1 or T2 if it is the
@@ -458,7 +458,7 @@ composite_pointer_type_r (tree t1, tree 
     }
 
   /* Merge the attributes.  */
-  attributes = (*targetm.merge_type_attributes) (t1, t2);
+  attributes = TARGET_MERGE_TYPE_ATTRIBUTES (t1, t2);
   return build_type_attribute_variant (result_type, attributes);
 }
 
@@ -517,7 +517,7 @@ composite_pointer_type (tree t1, tree t2
 				    | cp_type_quals (TREE_TYPE (t2))));
       result_type = build_pointer_type (result_type);
       /* Merge the attributes.  */
-      attributes = (*targetm.merge_type_attributes) (t1, t2);
+      attributes = TARGET_MERGE_TYPE_ATTRIBUTES (t1, t2);
       return build_type_attribute_variant (result_type, attributes);
     }
 
@@ -596,7 +596,7 @@ merge_types (tree t1, tree t2)
     return t1;
 
   /* Merge the attributes.  */
-  attributes = (*targetm.merge_type_attributes) (t1, t2);
+  attributes = TARGET_MERGE_TYPE_ATTRIBUTES (t1, t2);
 
   if (TYPE_PTRMEMFUNC_P (t1))
     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
@@ -976,7 +976,7 @@ comptypes (tree t1, tree t2, int strict)
   if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
     return true;
 
-  if (!(*targetm.comp_type_attributes) (t1, t2))
+  if (! TARGET_COMP_TYPE_ATTRIBUTES (t1, t2))
     return false;
 
   switch (TREE_CODE (t1))
@@ -5622,8 +5622,8 @@ convert_for_assignment (tree type, tree 
   coder = TREE_CODE (rhstype);
 
   if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
-      && ((*targetm.vector_opaque_p) (type)
-	  || (*targetm.vector_opaque_p) (rhstype)))
+      && (TARGET_VECTOR_OPAQUE_P (type)
+	  || TARGET_VECTOR_OPAQUE_P (rhstype)))
     return convert (type, rhs);
 
   if (rhs == error_mark_node || rhstype == error_mark_node)
diff -rup orig/egcc-CVS20031230/gcc/cse.c egcc-CVS20031230/gcc/cse.c
--- orig/egcc-CVS20031230/gcc/cse.c	2003-12-03 20:01:43.000000000 -0500
+++ egcc-CVS20031230/gcc/cse.c	2004-01-01 13:48:02.028817000 -0500
@@ -824,7 +824,7 @@ rtx_cost (rtx x, enum rtx_code outer_cod
     return 0;
 
   /* Compute the default costs of certain things.
-     Note that targetm.rtx_costs can override the defaults.  */
+     Note that TARGET_RTX_COSTS can override the defaults.  */
 
   code = GET_CODE (x);
   switch (code)
@@ -860,7 +860,7 @@ rtx_cost (rtx x, enum rtx_code outer_cod
       break;
 
     default:
-      if ((*targetm.rtx_costs) (x, code, outer_code, &total))
+      if (TARGET_RTX_COSTS (x, code, outer_code, &total))
 	return total;
       break;
     }
@@ -900,7 +900,7 @@ address_cost (rtx x, enum machine_mode m
   if (!memory_address_p (mode, x))
     return 1000;
 
-  return (*targetm.address_cost) (x);
+  return TARGET_ADDRESS_COST (x);
 }
 
 /* If the target doesn't override, compute the cost as with arithmetic.  */
diff -rup orig/egcc-CVS20031230/gcc/dbxout.c egcc-CVS20031230/gcc/dbxout.c
--- orig/egcc-CVS20031230/gcc/dbxout.c	2003-11-08 20:00:49.000000000 -0500
+++ egcc-CVS20031230/gcc/dbxout.c	2004-01-01 13:48:50.585677000 -0500
@@ -438,7 +438,7 @@ dbxout_function_end (void)
      the system doesn't insert underscores in front of user generated
      labels.  */
   ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);
-  (*targetm.asm_out.internal_label) (asmfile, "Lscope", scope_labelno);
+  TARGET_ASM_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno);
   scope_labelno++;
 
   /* By convention, GCC will mark the end of a function with an N_FUN
@@ -506,7 +506,7 @@ dbxout_init (const char *input_file_name
   assemble_name (asmfile, ltext_label_name);
   fputc ('\n', asmfile);
   text_section ();
-  (*targetm.asm_out.internal_label) (asmfile, "Ltext", 0);
+  TARGET_ASM_INTERNAL_LABEL (asmfile, "Ltext", 0);
 #endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */
 
 #ifdef DBX_OUTPUT_GCC_MARKER
@@ -717,7 +717,7 @@ dbxout_source_file (FILE *file, const ch
 	; /* Don't change section amid function.  */
       else
 	text_section ();
-      (*targetm.asm_out.internal_label) (file, "Ltext", source_label_number);
+      TARGET_ASM_INTERNAL_LABEL (file, "Ltext", source_label_number);
       source_label_number++;
       lastfile = filename;
     }
@@ -745,7 +745,7 @@ static void
 dbxout_begin_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
 {
   emit_pending_bincls_if_required ();
-  (*targetm.asm_out.internal_label) (asmfile, "LBB", n);
+  TARGET_ASM_INTERNAL_LABEL (asmfile, "LBB", n);
 }
 
 /* Describe the end line-number of an internal block within a function.  */
@@ -754,7 +754,7 @@ static void
 dbxout_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
 {
   emit_pending_bincls_if_required ();
-  (*targetm.asm_out.internal_label) (asmfile, "LBE", n);
+  TARGET_ASM_INTERNAL_LABEL (asmfile, "LBE", n);
 }
 
 /* Output dbx data for a function definition.
@@ -778,7 +778,7 @@ dbxout_function_decl (tree decl)
 #if defined(NO_DBX_FUNCTION_END)
       && ! NO_DBX_FUNCTION_END
 #endif
-      && targetm.have_named_sections)
+      && TARGET_HAVE_NAMED_SECTIONS)
     dbxout_function_end ();
 }
 
diff -rup orig/egcc-CVS20031230/gcc/defaults.h egcc-CVS20031230/gcc/defaults.h
--- orig/egcc-CVS20031230/gcc/defaults.h	2003-12-23 20:01:57.000000000 -0500
+++ egcc-CVS20031230/gcc/defaults.h	2004-01-01 13:49:42.612147000 -0500
@@ -81,7 +81,7 @@ Software Foundation, 59 Temple Place - S
 #ifndef ASM_OUTPUT_ADDR_VEC_ELT
 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE)  \
 do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
-     (*targetm.asm_out.internal_label) (FILE, "L", (VALUE));			\
+     TARGET_ASM_INTERNAL_LABEL (FILE, "L", (VALUE));			\
      fputc ('\n', FILE);						\
    } while (0)
 #endif
@@ -159,7 +159,7 @@ do { fputs (integer_asm_op (POINTER_SIZE
 
 #ifndef ASM_OUTPUT_DEBUG_LABEL
 #define ASM_OUTPUT_DEBUG_LABEL(FILE, PREFIX, NUM) \
-  (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
+  TARGET_ASM_INTERNAL_LABEL (FILE, PREFIX, NUM)
 #endif
 
 /* This is how we tell the assembler that a symbol is weak.  */
diff -rup orig/egcc-CVS20031230/gcc/dwarf2asm.c egcc-CVS20031230/gcc/dwarf2asm.c
--- orig/egcc-CVS20031230/gcc/dwarf2asm.c	2003-09-16 20:01:40.000000000 -0400
+++ egcc-CVS20031230/gcc/dwarf2asm.c	2004-01-01 13:52:20.672183000 -0500
@@ -516,7 +516,7 @@ dw2_asm_output_data_uleb128 (unsigned HO
 #else
   {
     unsigned HOST_WIDE_INT work = value;
-    const char *byte_op = targetm.asm_out.byte_op;
+    const char *byte_op = TARGET_ASM_BYTE_OP;
 
     if (byte_op)
       fputs (byte_op, asm_out_file);
@@ -578,7 +578,7 @@ dw2_asm_output_data_sleb128 (HOST_WIDE_I
   {
     HOST_WIDE_INT work = value;
     int more, byte;
-    const char *byte_op = targetm.asm_out.byte_op;
+    const char *byte_op = TARGET_ASM_BYTE_OP;
 
     if (byte_op)
       fputs (byte_op, asm_out_file);
@@ -707,7 +707,7 @@ dw2_force_const_mem (rtx x)
   if (GET_CODE (x) != SYMBOL_REF)
     abort ();
 
-  str = (* targetm.strip_name_encoding) (XSTR (x, 0));
+  str = TARGET_STRIP_NAME_ENCODING (XSTR (x, 0));
   node = splay_tree_lookup (indirect_pool, (splay_tree_key) str);
   if (node)
     decl = (tree) node->value;
diff -rup orig/egcc-CVS20031230/gcc/dwarf2out.c egcc-CVS20031230/gcc/dwarf2out.c
--- orig/egcc-CVS20031230/gcc/dwarf2out.c	2003-12-23 20:01:58.000000000 -0500
+++ egcc-CVS20031230/gcc/dwarf2out.c	2004-01-01 13:56:38.275618000 -0500
@@ -111,10 +111,10 @@ dwarf2out_do_frame (void)
 #define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
 #endif
 
-/* Various versions of targetm.eh_frame_section.  Note these must appear
+/* Various versions of TARGET_ASM_EH_FRAME_SECTION.  Note these must appear
    outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro guards.  */
 
-/* Version of targetm.eh_frame_section for systems with named sections.  */ 
+/* Version of TARGET_ASM_EH_FRAME_SECTION for systems with named sections.  */ 
 void
 named_section_eh_frame_section (void)
 {
@@ -140,7 +140,7 @@ named_section_eh_frame_section (void)
 #endif
 }
 
-/* Version of targetm.eh_frame_section for systems using collect2.  */ 
+/* Version of TARGET_ASM_EH_FRAME_SECTION for systems using collect2.  */ 
 void
 collect2_eh_frame_section (void)
 {
@@ -148,11 +148,11 @@ collect2_eh_frame_section (void)
 
   data_section ();
   ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
-  (*targetm.asm_out.globalize_label) (asm_out_file, IDENTIFIER_POINTER (label));
+  TARGET_ASM_GLOBALIZE_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
   ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
 }
 
-/* Default version of targetm.eh_frame_section.  */
+/* Default version of TARGET_ASM_EH_FRAME_SECTION.  */
 void
 default_eh_frame_section (void)
 {
@@ -1950,7 +1950,7 @@ output_call_frame_info (int for_eh)
     app_enable ();
 
   if (for_eh)
-    (*targetm.asm_out.eh_frame_section) ();
+    TARGET_ASM_EH_FRAME_SECTION ();
   else
     named_section_flags (DEBUG_FRAME_SECTION, SECTION_DEBUG);
 
@@ -2082,7 +2082,7 @@ output_call_frame_info (int for_eh)
 	  && !fde->uses_eh_lsda)
 	continue;
 
-      (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
+      TARGET_ASM_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2);
       ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
       ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
       dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1,
@@ -2167,7 +2167,7 @@ output_call_frame_info (int for_eh)
       ASM_OUTPUT_LABEL (asm_out_file, l2);
     }
 
-  if (for_eh && targetm.terminate_dw2_eh_frame_info)
+  if (for_eh && TARGET_TERMINATE_DW2_EH_FRAME_INFO)
     dw2_asm_output_data (4, 0, "End of Table");
 #ifdef MIPS_DEBUGGING_INFO
   /* Work around Irix 6 assembler bug whereby labels at the end of a section
@@ -6448,7 +6448,7 @@ output_die_symbol (dw_die_ref die)
     /* We make these global, not weak; if the target doesn't support
        .linkonce, it doesn't support combining the sections, so debugging
        will break.  */
-    (*targetm.asm_out.globalize_label) (asm_out_file, sym);
+    TARGET_ASM_GLOBALIZE_LABEL (asm_out_file, sym);
 
   ASM_OUTPUT_LABEL (asm_out_file, sym);
 }
@@ -8015,7 +8015,7 @@ reg_loc_descriptor (rtx rtl)
     return 0;
 
   reg = reg_number (rtl);
-  regs = (*targetm.dwarf_register_span) (rtl);
+  regs = TARGET_DWARF_REGISTER_SPAN (rtl);
 
   if (HARD_REGNO_NREGS (reg, GET_MODE (rtl)) > 1
       || regs)
@@ -8185,7 +8185,7 @@ mem_loc_descriptor (rtx rtl, enum machin
      actually within the array.  That's *not* necessarily the same as the
      zeroth element of the array.  */
 
-  rtl = (*targetm.delegitimize_address) (rtl);
+  rtl = TARGET_DELEGITIMIZE_ADDRESS (rtl);
 
   switch (GET_CODE (rtl))
     {
@@ -8609,7 +8609,7 @@ loc_descriptor_from_tree (tree loc, int 
 	mode = GET_MODE (rtl);
 	rtl = XEXP (rtl, 0);
 
-	rtl = (*targetm.delegitimize_address) (rtl);
+	rtl = TARGET_DELEGITIMIZE_ADDRESS (rtl);
 
 	indirect_p = 1;
 	ret = mem_loc_descriptor (rtl, mode);
@@ -9281,7 +9281,7 @@ rtl_for_decl_location (tree decl)
 	          && TREE_CODE (decl) == VAR_DECL
 		  && TREE_STATIC (decl))))
 	{
-	  rtl = (*targetm.delegitimize_address) (rtl);
+	  rtl = TARGET_DELEGITIMIZE_ADDRESS (rtl);
 	  return rtl;
 	}
       rtl = NULL_RTX;
@@ -9388,7 +9388,7 @@ rtl_for_decl_location (tree decl)
     }
 
   if (rtl)
-    rtl = (*targetm.delegitimize_address) (rtl);
+    rtl = TARGET_DELEGITIMIZE_ADDRESS (rtl);
 
   /* If we don't look past the constant pool, we risk emitting a
      reference to a constant pool entry that isn't referenced from
@@ -12381,7 +12381,7 @@ dwarf2out_source_line (unsigned int line
       else if (DECL_SECTION_NAME (current_function_decl))
 	{
 	  dw_separate_line_info_ref line_info;
-	  (*targetm.asm_out.internal_label) (asm_out_file, SEPARATE_LINE_CODE_LABEL,
+	  TARGET_ASM_INTERNAL_LABEL (asm_out_file, SEPARATE_LINE_CODE_LABEL,
 				     separate_line_info_table_in_use);
 
 	  /* expand the line info table if necessary */
@@ -12411,7 +12411,7 @@ dwarf2out_source_line (unsigned int line
 	{
 	  dw_line_info_ref line_info;
 
-	  (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
+	  TARGET_ASM_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
 				     line_info_table_in_use);
 
 	  /* Expand the line info table if necessary.  */
@@ -12917,7 +12917,7 @@ dwarf2out_finish (const char *filename)
 
   /* Output a terminator label for the .text section.  */
   text_section ();
-  (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
+  TARGET_ASM_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output the source line correspondence table.  We must do this
      even if there is no line information.  Otherwise, on an empty
diff -rup orig/egcc-CVS20031230/gcc/except.c egcc-CVS20031230/gcc/except.c
--- orig/egcc-CVS20031230/gcc/except.c	2003-11-14 09:05:01.000000000 -0500
+++ egcc-CVS20031230/gcc/except.c	2004-01-01 13:58:25.537122000 -0500
@@ -3519,7 +3519,7 @@ sjlj_output_call_site_table (void)
 void
 default_exception_section (void)
 {
-  if (targetm.have_named_sections)
+  if (TARGET_HAVE_NAMED_SECTIONS)
     {
       int flags;
 #ifdef HAVE_LD_RO_RW_SECTION_MIXING
@@ -3565,7 +3565,7 @@ output_function_exception_table (void)
   /* Note that varasm still thinks we're in the function's code section.
      The ".endp" directive that will immediately follow will take us back.  */
 #else
-  (*targetm.asm_out.exception_section) ();
+  TARGET_ASM_EXCEPTION_SECTION ();
 #endif
 
   have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
@@ -3586,7 +3586,7 @@ output_function_exception_table (void)
       assemble_align (tt_format_size * BITS_PER_UNIT);
     }
 
-  (*targetm.asm_out.internal_label) (asm_out_file, "LLSDA",
+  TARGET_ASM_INTERNAL_LABEL (asm_out_file, "LLSDA",
 			     current_function_funcdef_no);
 
   /* The LSDA header.  */
diff -rup orig/egcc-CVS20031230/gcc/expr.c egcc-CVS20031230/gcc/expr.c
--- orig/egcc-CVS20031230/gcc/expr.c	2003-12-19 21:40:00.000000000 -0500
+++ egcc-CVS20031230/gcc/expr.c	2004-01-01 13:58:59.604342000 -0500
@@ -2161,7 +2161,7 @@ copy_blkmode_from_reg (rtx tgtblk, rtx s
      holds if the structure is returned at the most significant
      end of the register.  */
   if (bytes % UNITS_PER_WORD != 0
-      && (targetm.calls.return_in_msb (type)
+      && (TARGET_RETURN_IN_MSB (type)
 	  ? !BYTES_BIG_ENDIAN
 	  : BYTES_BIG_ENDIAN))
     padding_correction
@@ -6872,7 +6872,7 @@ expand_expr (tree exp, rtx target, enum 
 		 && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
 		 && TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
 		 && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK
-		 && targetm.binds_local_p (array))
+		 && TARGET_BINDS_LOCAL_P (array))
 	  {
 	    if (TREE_CODE (index) == INTEGER_CST)
 	      {
diff -rup orig/egcc-CVS20031230/gcc/final.c egcc-CVS20031230/gcc/final.c
--- orig/egcc-CVS20031230/gcc/final.c	2003-12-21 20:01:16.000000000 -0500
+++ egcc-CVS20031230/gcc/final.c	2004-01-01 14:01:33.121643000 -0500
@@ -1385,7 +1385,7 @@ final_start_function (rtx first ATTRIBUT
     }
 
   /* First output the function prologue: code to set up the stack frame.  */
-  (*targetm.asm_out.function_prologue) (file, get_frame_size ());
+  TARGET_ASM_FUNCTION_PROLOGUE (file, get_frame_size ());
 
   /* If the machine represents the prologue as RTL, the profiling code must
      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
@@ -1412,7 +1412,7 @@ profile_function (FILE *file ATTRIBUTE_U
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
   int sval = current_function_returns_struct;
-  rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
+  rtx svrtx = TARGET_STRUCT_VALUE_RTX (TREE_TYPE (current_function_decl), 1);
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
   int cxt = current_function_needs_context;
 #endif
@@ -1423,7 +1423,7 @@ profile_function (FILE *file ATTRIBUTE_U
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
       data_section ();
       ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
-      (*targetm.asm_out.internal_label) (file, "LP", current_function_funcdef_no);
+      TARGET_ASM_INTERNAL_LABEL (file, "LP", current_function_funcdef_no);
       assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
     }
 
@@ -1479,7 +1479,7 @@ final_end_function (void)
 
   /* Finally, output the function epilogue:
      code to restore the stack frame and return to the caller.  */
-  (*targetm.asm_out.function_epilogue) (asm_out_file, get_frame_size ());
+  TARGET_ASM_FUNCTION_EPILOGUE (asm_out_file, get_frame_size ());
 
   /* And debug output.  */
   (*debug_hooks->end_epilogue) (last_linenum, last_filename);
@@ -1631,7 +1631,7 @@ output_alternate_entry_point (FILE *file
       ASM_WEAKEN_LABEL (file, name);
 #endif
     case LABEL_GLOBAL_ENTRY:
-      (*targetm.asm_out.globalize_label) (file, name);
+      TARGET_ASM_GLOBALIZE_LABEL (file, name);
     case LABEL_STATIC_ENTRY:
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
       ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
@@ -1707,12 +1707,12 @@ final_scan_insn (rtx insn, FILE *file, i
 	  break;
 
 	case NOTE_INSN_PROLOGUE_END:
-	  (*targetm.asm_out.function_end_prologue) (file);
+	  TARGET_ASM_FUNCTION_END_PROLOGUE (file);
 	  profile_after_prologue (file);
 	  break;
 
 	case NOTE_INSN_EPILOGUE_BEG:
-	  (*targetm.asm_out.function_begin_epilogue) (file);
+	  TARGET_ASM_FUNCTION_BEGIN_EPILOGUE (file);
 	  break;
 
 	case NOTE_INSN_FUNCTION_BEG:
@@ -1885,7 +1885,7 @@ final_scan_insn (rtx insn, FILE *file, i
 	      ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
 				     NEXT_INSN (insn));
 #else
-	      (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
+	      TARGET_ASM_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
 #endif
 	      break;
@@ -1894,7 +1894,7 @@ final_scan_insn (rtx insn, FILE *file, i
       if (LABEL_ALT_ENTRY_P (insn))
 	output_alternate_entry_point (file, insn);
       else
-	(*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
+	TARGET_ASM_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
       break;
 
     default:
@@ -3242,9 +3242,9 @@ output_addr_const (FILE *file, rtx x)
 	output_addr_const (file, XEXP (x, 1));
       else
 	{
-	  fputs (targetm.asm_out.open_paren, file);
+	  fputs (TARGET_ASM_OPEN_PAREN, file);
 	  output_addr_const (file, XEXP (x, 1));
-	  fputs (targetm.asm_out.close_paren, file);
+	  fputs (TARGET_ASM_CLOSE_PAREN, file);
 	}
       break;
 
diff -rup orig/egcc-CVS20031230/gcc/function.c egcc-CVS20031230/gcc/function.c
--- orig/egcc-CVS20031230/gcc/function.c	2003-12-30 20:01:21.000000000 -0500
+++ egcc-CVS20031230/gcc/function.c	2004-01-01 14:04:12.377895000 -0500
@@ -4242,7 +4242,7 @@ aggregate_value_p (tree exp, tree fntype
 
   if (TREE_CODE (type) == VOID_TYPE)
     return 0;
-  if (targetm.calls.return_in_memory (type, fntype))
+  if (TARGET_RETURN_IN_MEMORY (type, fntype))
     return 1;
   /* Types that are TREE_ADDRESSABLE must be constructed in memory,
      and thus can't be returned in registers.  */
@@ -4321,7 +4321,7 @@ assign_parms (tree fndecl)
   /* If struct value address is treated as the first argument, make it so.  */
   if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
       && ! current_function_returns_pcc_struct
-      && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
+      && TARGET_STRUCT_VALUE_RTX (TREE_TYPE (fndecl), 1) == 0)
     {
       tree type = build_pointer_type (TREE_TYPE (fntype));
 
@@ -4391,7 +4391,7 @@ assign_parms (tree fndecl)
       /* Set NAMED_ARG if this arg should be treated as a named arg.  For
 	 most machines, if this is a varargs/stdarg function, then we treat
 	 the last named arg as if it were anonymous too.  */
-      named_arg = targetm.calls.strict_argument_naming (&args_so_far) ? 1 : ! last_named;
+      named_arg = TARGET_STRICT_ARGUMENT_NAMING (&args_so_far) ? 1 : ! last_named;
 
       if (TREE_TYPE (parm) == error_mark_node
 	  /* This can happen after weird syntax errors
@@ -4456,7 +4456,7 @@ assign_parms (tree fndecl)
 
       promoted_mode = passed_mode;
 
-      if (targetm.calls.promote_function_args (TREE_TYPE (fndecl)))
+      if (TARGET_PROMOTE_FUNCTION_ARGS (TREE_TYPE (fndecl)))
 	{
 	  /* Compute the mode in which the arg is actually extended to.  */
 	  unsignedp = TREE_UNSIGNED (passed_type);
@@ -4489,7 +4489,7 @@ assign_parms (tree fndecl)
       if (last_named && !varargs_setup)
 	{
 	  int varargs_pretend_bytes = 0;
-	  targetm.calls.setup_incoming_varargs (&args_so_far, promoted_mode,
+	  TARGET_SETUP_INCOMING_VARARGS (&args_so_far, promoted_mode,
 						passed_type,
 						&varargs_pretend_bytes, 0);
 	  varargs_setup = 1;
@@ -4520,7 +4520,7 @@ assign_parms (tree fndecl)
       if (!in_regs && !named_arg)
 	{
 	  int pretend_named =
-	    targetm.calls.pretend_outgoing_varargs_named (&args_so_far);
+	    TARGET_PRETEND_OUTGOING_VARARGS_NAMED (&args_so_far);
 	  if (pretend_named)
 	    {
 #ifdef FUNCTION_INCOMING_ARG
@@ -6654,7 +6654,7 @@ expand_function_start (tree subr, int pa
       else
 #endif
 	{
-	  rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 1);
+	  rtx sv = TARGET_STRUCT_VALUE_RTX (TREE_TYPE (subr), 1);
 	  /* Expect to be passed the address of a place to store the value.
 	     If it is passed as an argument, assign_parms will take care of
 	     it.  */
@@ -7096,7 +7096,7 @@ expand_function_end (void)
 	    {
 	      int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));
 
-	      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+	      if (TARGET_PROMOTE_FUNCTION_RETURN (TREE_TYPE (current_function_decl)))
 		promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
 			      &unsignedp, 1);
 
diff -rup orig/egcc-CVS20031230/gcc/haifa-sched.c egcc-CVS20031230/gcc/haifa-sched.c
--- orig/egcc-CVS20031230/gcc/haifa-sched.c	2003-12-21 20:01:18.000000000 -0500
+++ egcc-CVS20031230/gcc/haifa-sched.c	2004-01-01 14:37:37.403425000 -0500
@@ -874,8 +874,8 @@ insn_cost (rtx insn, rtx link, rtx used)
 	}
       else
 	{
-	  if (targetm.sched.use_dfa_pipeline_interface
-	      && (*targetm.sched.use_dfa_pipeline_interface) ())
+	  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+	      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	    cost = insn_default_latency (insn);
 	  else
 	    cost = result_ready_cost (insn);
@@ -898,8 +898,8 @@ insn_cost (rtx insn, rtx link, rtx used)
     cost = 0;
   else
     {
-      if (targetm.sched.use_dfa_pipeline_interface
-	  && (*targetm.sched.use_dfa_pipeline_interface) ())
+      if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+	  && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	{
 	  if (INSN_CODE (insn) >= 0)
 	    {
@@ -917,8 +917,8 @@ insn_cost (rtx insn, rtx link, rtx used)
 	    }
 	}
 
-      if (targetm.sched.adjust_cost)
-	cost = (*targetm.sched.adjust_cost) (used, link, insn, cost);
+      if (TARGET_SCHED_ADJUST_COST != 0)
+	cost = TARGET_SCHED_ADJUST_COST (used, link, insn, cost);
 
       if (cost < 0)
 	cost = 0;
@@ -1208,7 +1208,7 @@ adjust_priority (rtx prev)
 
      Revisit when we have a machine model to work with and not before.  */
 
-  if (targetm.sched.adjust_priority)
+  if (TARGET_SCHED_ADJUST_PRIORITY)
     INSN_PRIORITY (prev) =
       (*targetm.sched.adjust_priority) (prev, INSN_PRIORITY (prev));
 }
@@ -1217,16 +1217,16 @@ adjust_priority (rtx prev)
 HAIFA_INLINE static void
 advance_one_cycle (void)
 {
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
-      if (targetm.sched.dfa_pre_cycle_insn)
+      if (TARGET_SCHED_DFA_PRE_CYCLE_INSN)
 	state_transition (curr_state,
 			  (*targetm.sched.dfa_pre_cycle_insn) ());
 
       state_transition (curr_state, NULL);
 
-      if (targetm.sched.dfa_post_cycle_insn)
+      if (TARGET_SCHED_DFA_POST_CYCLE_INSN)
 	state_transition (curr_state,
 			  (*targetm.sched.dfa_post_cycle_insn) ());
     }
@@ -1249,12 +1249,12 @@ schedule_insn (rtx insn, struct ready_li
   int unit = 0;
   int premature_issue = 0;
 
-  if (!targetm.sched.use_dfa_pipeline_interface
-      || !(*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+      || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     unit = insn_unit (insn);
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ()
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ()
       && sched_verbose >= 1)
     {
       char buf[2048];
@@ -1277,8 +1277,8 @@ schedule_insn (rtx insn, struct ready_li
       fputc ('\n', sched_dump);
     }
 
-  if (!targetm.sched.use_dfa_pipeline_interface
-      || !(*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+      || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
       if (sched_verbose && unit == -1)
 	visualize_no_unit (insn);
@@ -1807,8 +1807,8 @@ queue_to_ready (struct ready_list *ready
 	  advance_one_cycle ();
 	}
 
-      if ((!targetm.sched.use_dfa_pipeline_interface
-	   || !(*targetm.sched.use_dfa_pipeline_interface) ())
+      if ((TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+	   || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	  && sched_verbose && stalls)
 	visualize_stall_cycles (stalls);
 
@@ -1834,7 +1834,7 @@ ok_for_early_queue_removal (rtx insn)
   int n_cycles;
   rtx prev_insn = last_scheduled_insn;
 
-  if (targetm.sched.is_costly_dependence)
+  if (TARGET_SCHED_IS_COSTLY_DEPENDENCE)
     {
       for (n_cycles = flag_sched_stalled_insns_dep; n_cycles; n_cycles--)
 	{
@@ -2193,8 +2193,8 @@ choose_ready (struct ready_list *ready)
 {
   int lookahead = 0;
 
-  if (targetm.sched.first_cycle_multipass_dfa_lookahead)
-    lookahead = (*targetm.sched.first_cycle_multipass_dfa_lookahead) ();
+  if (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD != 0)
+    lookahead = TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ();
   if (lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0)))
     return ready_remove_first (ready);
   else
@@ -2218,7 +2218,7 @@ choose_ready (struct ready_list *ready)
 	  insn = ready_element (ready, i);
 	  ready_try [i]
 	    = (INSN_CODE (insn) < 0
-	       || (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
+	       || (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
 		   && !(*targetm.sched.first_cycle_multipass_dfa_lookahead_guard) (insn)));
 	}
       if (max_issue (ready, &index) == 0)
@@ -2282,8 +2282,8 @@ schedule_block (int b, int rgn_n_insns)
       init_block_visualization ();
     }
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     state_reset (curr_state);
   else
     clear_units ();
@@ -2294,8 +2294,8 @@ schedule_block (int b, int rgn_n_insns)
   ready.vec = xmalloc (ready.veclen * sizeof (rtx));
   ready.n_ready = 0;
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
       /* It is used for first cycle multipass scheduling.  */
       temp_state = alloca (dfa_state_size);
@@ -2308,8 +2308,8 @@ schedule_block (int b, int rgn_n_insns)
 
   (*current_sched_info->init_ready_list) (&ready);
 
-  if (targetm.sched.md_init)
-    (*targetm.sched.md_init) (sched_dump, sched_verbose, ready.veclen);
+  if (TARGET_SCHED_INIT != 0)
+    TARGET_SCHED_INIT (sched_dump, sched_verbose, ready.veclen);
 
   /* We start inserting insns after PREV_HEAD.  */
   last_scheduled_insn = prev_head;
@@ -2319,8 +2319,8 @@ schedule_block (int b, int rgn_n_insns)
   q_ptr = 0;
   q_size = 0;
 
-  if (!targetm.sched.use_dfa_pipeline_interface
-      || !(*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+      || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     max_insn_queue_index_macro_value = INSN_QUEUE_SIZE - 1;
   else
     max_insn_queue_index_macro_value = max_insn_queue_index;
@@ -2377,7 +2377,7 @@ schedule_block (int b, int rgn_n_insns)
 
       /* Allow the target to reorder the list, typically for
 	 better instruction bundling.  */
-      if (sort_p && targetm.sched.reorder
+      if (sort_p && TARGET_SCHED_REORDER
 	  && (ready.n_ready == 0
 	      || !SCHED_GROUP_P (ready_element (&ready, 0))))
 	can_issue_more =
@@ -2401,8 +2401,8 @@ schedule_block (int b, int rgn_n_insns)
 	      debug_ready_list (&ready);
 	    }
 
-	  if (!targetm.sched.use_dfa_pipeline_interface
-	      || !(*targetm.sched.use_dfa_pipeline_interface) ())
+	  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+	      || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	    {
 	      if (ready.n_ready == 0 || !can_issue_more
 		  || !(*current_sched_info->schedule_more_p) ())
@@ -2437,7 +2437,7 @@ schedule_block (int b, int rgn_n_insns)
 	      else
 		insn = ready_remove_first (&ready);
 
-	      if (targetm.sched.dfa_new_cycle
+	      if (TARGET_SCHED_DFA_NEW_CYCLE
 		  && (*targetm.sched.dfa_new_cycle) (sched_dump, sched_verbose,
 						     insn, last_clock_var,
 						     clock_var, &sort_p))
@@ -2467,8 +2467,8 @@ schedule_block (int b, int rgn_n_insns)
 		{
 		  cost = state_transition (temp_state, insn);
 
-		  if (targetm.sched.first_cycle_multipass_dfa_lookahead
-		      && targetm.sched.dfa_bubble)
+		  if (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD != 0
+		      && TARGET_SCHED_DFA_BUBBLE)
 		    {
 		      if (cost == 0)
 			{
@@ -2548,15 +2548,15 @@ schedule_block (int b, int rgn_n_insns)
 
 	  last_scheduled_insn = move_insn (insn, last_scheduled_insn);
 
-	  if (targetm.sched.use_dfa_pipeline_interface
-	      && (*targetm.sched.use_dfa_pipeline_interface) ())
+	  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+	      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	    {
 	      if (memcmp (curr_state, temp_state, dfa_state_size) != 0)
 		cycle_issued_insns++;
 	      memcpy (curr_state, temp_state, dfa_state_size);
 	    }
 
-	  if (targetm.sched.variable_issue)
+	  if (TARGET_SCHED_VARIABLE_ISSUE)
 	    can_issue_more =
 	      (*targetm.sched.variable_issue) (sched_dump, sched_verbose,
 					       insn, can_issue_more);
@@ -2579,7 +2579,7 @@ schedule_block (int b, int rgn_n_insns)
 	  if (ready.n_ready > 0)
 	    ready_sort (&ready);
 
-	  if (targetm.sched.reorder2
+	  if (TARGET_SCHED_REORDER2
 	      && (ready.n_ready == 0
 		  || !SCHED_GROUP_P (ready_element (&ready, 0))))
 	    {
@@ -2591,14 +2591,14 @@ schedule_block (int b, int rgn_n_insns)
 	    }
 	}
 
-      if ((!targetm.sched.use_dfa_pipeline_interface
-	   || !(*targetm.sched.use_dfa_pipeline_interface) ())
+      if ((TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+	   || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	  && sched_verbose)
 	/* Debug info.  */
 	visualize_scheduled_insns (clock_var);
     }
 
-  if (targetm.sched.md_finish)
+  if (TARGET_SCHED_FINISH)
     (*targetm.sched.md_finish) (sched_dump, sched_verbose);
 
   /* Debug info.  */
@@ -2606,8 +2606,8 @@ schedule_block (int b, int rgn_n_insns)
     {
       fprintf (sched_dump, ";;\tReady list (final):  ");
       debug_ready_list (&ready);
-      if (!targetm.sched.use_dfa_pipeline_interface
-	  || !(*targetm.sched.use_dfa_pipeline_interface) ())
+      if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+	  || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	print_block_visualization ("");
     }
 
@@ -2675,8 +2675,8 @@ schedule_block (int b, int rgn_n_insns)
 
   free (ready.vec);
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
       free (ready_try);
       for (i = 0; i <= rgn_n_insns; i++)
@@ -2748,8 +2748,8 @@ sched_init (FILE *dump_file)
 		? stderr : dump_file);
 
   /* Initialize issue_rate.  */
-  if (targetm.sched.issue_rate)
-    issue_rate = (*targetm.sched.issue_rate) ();
+  if (TARGET_SCHED_ISSUE_RATE != 0)
+    issue_rate = TARGET_SCHED_ISSUE_RATE ();
   else
     issue_rate = 1;
 
@@ -2769,17 +2769,17 @@ sched_init (FILE *dump_file)
   for (i = 0; i < old_max_uid; i++)
     h_i_d [i].cost = -1;
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
-      if (targetm.sched.init_dfa_pre_cycle_insn)
+      if (TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN)
 	(*targetm.sched.init_dfa_pre_cycle_insn) ();
 
-      if (targetm.sched.init_dfa_post_cycle_insn)
+      if (TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN)
 	(*targetm.sched.init_dfa_post_cycle_insn) ();
 
-      if (targetm.sched.first_cycle_multipass_dfa_lookahead
-	  && targetm.sched.init_dfa_bubbles)
+      if (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD != 0
+	  && TARGET_SCHED_INIT_DFA_BUBBLES)
 	(*targetm.sched.init_dfa_bubbles) ();
 
       dfa_start ();
@@ -2842,8 +2842,8 @@ sched_init (FILE *dump_file)
 	}
     }
 
-  if ((!targetm.sched.use_dfa_pipeline_interface
-       || !(*targetm.sched.use_dfa_pipeline_interface) ())
+  if ((TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+       || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
       && sched_verbose)
     /* Find units used in this function, for visualization.  */
     init_target_units ();
@@ -2876,8 +2876,8 @@ sched_finish (void)
 {
   free (h_i_d);
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
       free (curr_state);
       dfa_finish ();
diff -rup orig/egcc-CVS20031230/gcc/ifcvt.c egcc-CVS20031230/gcc/ifcvt.c
--- orig/egcc-CVS20031230/gcc/ifcvt.c	2003-12-30 20:01:22.000000000 -0500
+++ egcc-CVS20031230/gcc/ifcvt.c	2004-01-01 14:14:50.435592000 -0500
@@ -3207,7 +3207,7 @@ if_convert (int x_life_data_ok)
   num_true_changes = 0;
   life_data_ok = (x_life_data_ok != 0);
 
-  if (! (* targetm.cannot_modify_jumps_p) ())
+  if (! TARGET_CANNOT_MODIFY_JUMPS_P ())
     mark_loop_exit_edges ();
 
   /* Free up basic_block_for_insn so that we don't have to keep it
diff -rup orig/egcc-CVS20031230/gcc/integrate.c egcc-CVS20031230/gcc/integrate.c
--- orig/egcc-CVS20031230/gcc/integrate.c	2003-12-15 20:01:34.000000000 -0500
+++ egcc-CVS20031230/gcc/integrate.c	2004-01-01 14:16:36.336689000 -0500
@@ -119,7 +119,7 @@ get_label_from_map (struct inline_remap 
 bool
 function_attribute_inlinable_p (tree fndecl)
 {
-  if (targetm.attribute_table)
+  if (TARGET_ATTRIBUTE_TABLE)
     {
       tree a;
 
diff -rup orig/egcc-CVS20031230/gcc/optabs.c egcc-CVS20031230/gcc/optabs.c
--- orig/egcc-CVS20031230/gcc/optabs.c	2003-11-21 20:00:48.000000000 -0500
+++ egcc-CVS20031230/gcc/optabs.c	2004-01-01 14:40:03.642626000 -0500
@@ -5132,7 +5132,7 @@ init_one_libfunc (const char *name)
   rtx symbol;
 
   /* Create a FUNCTION_DECL that can be passed to
-     targetm.encode_section_info.  */
+     TARGET_ENCODE_SECTION_INFO.  */
   /* ??? We don't have any type information except for this is
      a function.  Pretend this is "int foo()".  */
   tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
@@ -5144,7 +5144,7 @@ init_one_libfunc (const char *name)
   symbol = XEXP (DECL_RTL (decl), 0);
 
   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
-     are the flags assigned by targetm.encode_section_info.  */
+     are the flags assigned by TARGET_ENCODE_SECTION_INFO.  */
   SYMBOL_REF_DECL (symbol) = 0;
 
   return symbol;
@@ -5412,7 +5412,7 @@ init_optabs (void)
     trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
 
   /* Allow the target to add more libcalls or rename some, etc.  */
-  targetm.init_libfuncs ();
+  TARGET_INIT_LIBFUNCS ();
 }
 \f
 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
diff -rup orig/egcc-CVS20031230/gcc/predict.c egcc-CVS20031230/gcc/predict.c
--- orig/egcc-CVS20031230/gcc/predict.c	2003-12-30 20:01:23.000000000 -0500
+++ egcc-CVS20031230/gcc/predict.c	2004-01-01 14:40:27.061286000 -0500
@@ -1227,7 +1227,7 @@ static void
 choose_function_section (void)
 {
   if (DECL_SECTION_NAME (current_function_decl)
-      || !targetm.have_named_sections
+      || !TARGET_HAVE_NAMED_SECTIONS
       /* Theoretically we can split the gnu.linkonce text section too,
 	 but this requires more work as the frequency needs to match
 	 for all generated objects so we need to merge the frequency
diff -rup orig/egcc-CVS20031230/gcc/sched-ebb.c egcc-CVS20031230/gcc/sched-ebb.c
--- orig/egcc-CVS20031230/gcc/sched-ebb.c	2003-12-10 20:01:31.000000000 -0500
+++ egcc-CVS20031230/gcc/sched-ebb.c	2004-01-01 14:42:25.162189000 -0500
@@ -498,7 +498,7 @@ schedule_ebb (rtx head, rtx tail)
 
   add_deps_for_risky_insns (head, tail);
 
-  if (targetm.sched.dependencies_evaluation_hook)
+  if (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK)
     targetm.sched.dependencies_evaluation_hook (head, tail);
 
   /* Set priorities.  */
diff -rup orig/egcc-CVS20031230/gcc/sched-rgn.c egcc-CVS20031230/gcc/sched-rgn.c
--- orig/egcc-CVS20031230/gcc/sched-rgn.c	2003-12-30 20:01:23.000000000 -0500
+++ egcc-CVS20031230/gcc/sched-rgn.c	2004-01-01 14:46:26.963416000 -0500
@@ -1759,7 +1759,7 @@ init_ready_list (struct ready_list *read
 	{
 	  ready_add (ready, insn);
 
-	  if (targetm.sched.adjust_priority)
+	  if (TARGET_SCHED_ADJUST_PRIORITY)
 	    INSN_PRIORITY (insn) =
 	      (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
 	}
@@ -1787,11 +1787,11 @@ init_ready_list (struct ready_list *read
 
 	    if (!CANT_MOVE (insn)
 		&& (!IS_SPECULATIVE_INSN (insn)
-		    || ((((!targetm.sched.use_dfa_pipeline_interface
-			   || !(*targetm.sched.use_dfa_pipeline_interface) ())
+		    || ((((TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+			   || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 			  && insn_issue_delay (insn) <= 3)
-			 || (targetm.sched.use_dfa_pipeline_interface
-			     && (*targetm.sched.use_dfa_pipeline_interface) ()
+			 || (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+			     && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ()
 			     && (recog_memoized (insn) < 0
 			         || min_insn_conflict_delay (curr_state,
 							     insn, insn) <= 3)))
@@ -1801,7 +1801,7 @@ init_ready_list (struct ready_list *read
 		{
 		  ready_add (ready, insn); 
 
-		  if (targetm.sched.adjust_priority)
+		  if (TARGET_SCHED_ADJUST_PRIORITY)
 		    INSN_PRIORITY (insn) =
 		      (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
 		}
@@ -1886,13 +1886,13 @@ new_ready (rtx next)
 	  || CANT_MOVE (next)
 	  || (IS_SPECULATIVE_INSN (next)
 	      && (0
-		  || (targetm.sched.use_dfa_pipeline_interface
-		      && (*targetm.sched.use_dfa_pipeline_interface) ()
+		  || (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+		      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ()
 		      && recog_memoized (next) >= 0
 		      && min_insn_conflict_delay (curr_state, next,
 						  next) > 3)
-		  || ((!targetm.sched.use_dfa_pipeline_interface
-		       || !(*targetm.sched.use_dfa_pipeline_interface) ())
+		  || ((TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE == 0
+		       || !TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 		      && insn_issue_delay (next) > 3)
 		  || !check_live (next, INSN_BB (next))
 		  || !is_exception_free (next, INSN_BB (next), target_bb)))))
@@ -2292,8 +2292,8 @@ debug_dependencies (void)
 	  fprintf (sched_dump, "\n;;   --- Region Dependences --- b %d bb %d \n",
 		   BB_TO_BLOCK (bb), bb);
 
-	  if (targetm.sched.use_dfa_pipeline_interface
-	      && (*targetm.sched.use_dfa_pipeline_interface) ())
+	  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+	      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 	    {
 	      fprintf (sched_dump, ";;   %7s%6s%6s%6s%6s%6s%14s\n",
 		       "insn", "code", "bb", "dep", "prio", "cost",
@@ -2332,8 +2332,8 @@ debug_dependencies (void)
 		  continue;
 		}
 
-	      if (targetm.sched.use_dfa_pipeline_interface
-		  && (*targetm.sched.use_dfa_pipeline_interface) ())
+	      if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+		  && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
 		{
 		  fprintf (sched_dump,
 			   ";;   %s%5d%6d%6d%6d%6d%6d   ",
@@ -2416,7 +2416,7 @@ schedule_region (int rgn)
 
       compute_forward_dependences (head, tail);
 
-      if (targetm.sched.dependencies_evaluation_hook)
+      if (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK)
 	targetm.sched.dependencies_evaluation_hook (head, tail);
 
     }
diff -rup orig/egcc-CVS20031230/gcc/sched-vis.c egcc-CVS20031230/gcc/sched-vis.c
--- orig/egcc-CVS20031230/gcc/sched-vis.c	2003-12-13 20:01:20.000000000 -0500
+++ egcc-CVS20031230/gcc/sched-vis.c	2004-01-01 14:48:19.684642000 -0500
@@ -125,8 +125,8 @@ get_visual_tbl_length (void)
   int n, n1;
   char *s;
 
-  if (targetm.sched.use_dfa_pipeline_interface
-      && (*targetm.sched.use_dfa_pipeline_interface) ())
+  if (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE != 0
+      && TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ())
     {
       visual_tbl_line_length = 1;
       return 1; /* Can't return 0 because that will cause problems
diff -rup orig/egcc-CVS20031230/gcc/simplify-rtx.c egcc-CVS20031230/gcc/simplify-rtx.c
--- orig/egcc-CVS20031230/gcc/simplify-rtx.c	2003-12-05 20:01:14.000000000 -0500
+++ egcc-CVS20031230/gcc/simplify-rtx.c	2004-01-01 14:49:22.599902000 -0500
@@ -131,7 +131,7 @@ avoid_constant_pool_reference (rtx x)
   addr = XEXP (x, 0);
 
   /* Call target hook to avoid the effects of -fpic etc....  */
-  addr = (*targetm.delegitimize_address) (addr);
+  addr = TARGET_DELEGITIMIZE_ADDRESS (addr);
 
   if (GET_CODE (addr) == LO_SUM)
     addr = XEXP (addr, 1);
diff -rup orig/egcc-CVS20031230/gcc/stmt.c egcc-CVS20031230/gcc/stmt.c
--- orig/egcc-CVS20031230/gcc/stmt.c	2003-12-20 20:01:08.000000000 -0500
+++ egcc-CVS20031230/gcc/stmt.c	2004-01-01 14:50:01.056876000 -0500
@@ -2953,7 +2953,7 @@ shift_return_value (rtx val)
   tree type;
 
   type = TREE_TYPE (DECL_RESULT (current_function_decl));
-  if (targetm.calls.return_in_msb (type))
+  if (TARGET_RETURN_IN_MSB (type))
     {
       rtx target;
       HOST_WIDE_INT shift;
@@ -3000,7 +3000,7 @@ expand_value_return (rtx val)
   if (return_reg != val)
     {
       tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
-      if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+      if (TARGET_PROMOTE_FUNCTION_RETURN (TREE_TYPE (current_function_decl)))
       {
 	int unsignedp = TREE_UNSIGNED (type);
 	enum machine_mode old_mode
@@ -3162,7 +3162,7 @@ expand_return (tree retval)
 	 holds if the structure is returned at the most significant
 	 end of the register.  */
       if (bytes % UNITS_PER_WORD != 0
-	  && (targetm.calls.return_in_msb (TREE_TYPE (retval_rhs))
+	  && (TARGET_RETURN_IN_MSB (TREE_TYPE (retval_rhs))
 	      ? !BYTES_BIG_ENDIAN
 	      : BYTES_BIG_ENDIAN))
 	padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
diff -rup orig/egcc-CVS20031230/gcc/stor-layout.c egcc-CVS20031230/gcc/stor-layout.c
--- orig/egcc-CVS20031230/gcc/stor-layout.c	2003-12-30 20:01:23.000000000 -0500
+++ egcc-CVS20031230/gcc/stor-layout.c	2004-01-01 14:51:06.241903000 -0500
@@ -407,7 +407,7 @@ layout_decl (tree decl, unsigned int kno
 	     field.  */
 	  if (integer_zerop (DECL_SIZE (decl))
 	      && ! DECL_PACKED (decl)
-	      && ! (*targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (decl)))
+	      && ! TARGET_MS_BITFIELD_LAYOUT_P (DECL_FIELD_CONTEXT (decl)))
 	    {
 #ifdef PCC_BITFIELD_TYPE_MATTERS
 	      if (PCC_BITFIELD_TYPE_MATTERS)
@@ -707,7 +707,7 @@ update_alignment_for_field (record_layou
   /* Record must have at least as much alignment as any field.
      Otherwise, the alignment of the field within the record is
      meaningless.  */
-  if (is_bitfield && (* targetm.ms_bitfield_layout_p) (rli->t))
+  if (is_bitfield && TARGET_MS_BITFIELD_LAYOUT_P (rli->t))
     {
       /* Here, the alignment of the underlying type of a bitfield can
 	 affect the alignment of a record; even a zero-sized field
@@ -927,7 +927,7 @@ place_field (record_layout_info rli, tre
      variable-sized fields, we need not worry about compatibility.  */
 #ifdef PCC_BITFIELD_TYPE_MATTERS
   if (PCC_BITFIELD_TYPE_MATTERS
-      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
+      && ! TARGET_MS_BITFIELD_LAYOUT_P (rli->t)
       && TREE_CODE (field) == FIELD_DECL
       && type != error_mark_node
       && DECL_BIT_FIELD (field)
@@ -960,7 +960,7 @@ place_field (record_layout_info rli, tre
 
 #ifdef BITFIELD_NBYTES_LIMITED
   if (BITFIELD_NBYTES_LIMITED
-      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
+      && ! TARGET_MS_BITFIELD_LAYOUT_P (rli->t)
       && TREE_CODE (field) == FIELD_DECL
       && type != error_mark_node
       && DECL_BIT_FIELD_TYPE (field)
@@ -1011,7 +1011,7 @@ place_field (record_layout_info rli, tre
      Note: for compatibility, we use the type size, not the type alignment
      to determine alignment, since that matches the documentation */
 
-  if ((* targetm.ms_bitfield_layout_p) (rli->t)
+  if (TARGET_MS_BITFIELD_LAYOUT_P (rli->t)
        && ((DECL_BIT_FIELD_TYPE (field) && ! DECL_PACKED (field))
 	  || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
     {
diff -rup orig/egcc-CVS20031230/gcc/target-def.h egcc-CVS20031230/gcc/target-def.h
--- orig/egcc-CVS20031230/gcc/target-def.h	2003-12-04 20:02:19.000000000 -0500
+++ egcc-CVS20031230/gcc/target-def.h	2003-12-31 10:12:53.500816000 -0500
@@ -396,3 +396,4 @@ Foundation, 59 Temple Place - Suite 330,
 
 #include "hooks.h"
 #include "targhooks.h"
+#include "config/sparc/redef.h"
diff -rup orig/egcc-CVS20031230/gcc/target.h egcc-CVS20031230/gcc/target.h
--- orig/egcc-CVS20031230/gcc/target.h	2003-12-04 20:02:19.000000000 -0500
+++ egcc-CVS20031230/gcc/target.h	2003-12-31 10:12:53.510760000 -0500
@@ -439,3 +439,5 @@ struct gcc_target
 };
 
 extern struct gcc_target targetm;
+
+#include "target-def.h"
diff -rup orig/egcc-CVS20031230/gcc/targhooks.c egcc-CVS20031230/gcc/targhooks.c
--- orig/egcc-CVS20031230/gcc/targhooks.c	2003-12-18 20:02:14.000000000 -0500
+++ egcc-CVS20031230/gcc/targhooks.c	2004-01-01 14:52:15.746464000 -0500
@@ -60,7 +60,6 @@ Software Foundation, 59 Temple Place - S
 #include "function.h"
 #include "target.h"
 #include "tm_p.h"
-#include "target-def.h"
 
 void
 default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
@@ -188,7 +187,7 @@ default_pretend_outgoing_varargs_named(C
 #ifdef SETUP_INCOMING_VARARGS
   return 1;
 #else
-  return (targetm.calls.setup_incoming_varargs != default_setup_incoming_varargs);
+  return (TARGET_SETUP_INCOMING_VARARGS != default_setup_incoming_varargs);
 #endif
 }
 
diff -rup orig/egcc-CVS20031230/gcc/toplev.c egcc-CVS20031230/gcc/toplev.c
--- orig/egcc-CVS20031230/gcc/toplev.c	2003-12-30 20:01:24.000000000 -0500
+++ egcc-CVS20031230/gcc/toplev.c	2004-01-01 14:55:20.383034000 -0500
@@ -1853,7 +1853,7 @@ compile_file (void)
       timevar_pop (TV_DUMP);
     }
 
-  targetm.asm_out.file_end ();
+  TARGET_ASM_FILE_END ();
 
   /* Attach a special .ident directive to the end of the file to identify
      the version of GCC which compiled this code.  The format of the .ident
@@ -3519,7 +3519,7 @@ rest_of_compilation (tree decl)
   /* CFG is no longer maintained up-to-date.  */
   free_bb_for_insn ();
 
-  if (targetm.machine_dependent_reorg != 0)
+  if (TARGET_MACHINE_DEPENDENT_REORG != 0)
     rest_of_handle_machine_reorg (decl, insns);
 
   purge_line_number_notes (insns);
@@ -3597,7 +3597,7 @@ rest_of_compilation (tree decl)
 
   timevar_pop (TV_FINAL);
 
-  if ((*targetm.binds_local_p) (current_function_decl))
+  if (TARGET_BINDS_LOCAL_P (current_function_decl))
     {
       int pref = cfun->preferred_stack_boundary;
       if (cfun->recursive_call_emit
@@ -3987,7 +3987,7 @@ init_asm_output (const char *name)
 
   if (!flag_syntax_only)
     {
-      targetm.asm_out.file_start ();
+      TARGET_ASM_FILE_START ();
 
 #ifdef ASM_COMMENT_START
       if (flag_verbose_asm)
@@ -4377,7 +4377,7 @@ process_options (void)
 	fatal_error ("can't open %s: %m", aux_info_file_name);
     }
 
-  if (! targetm.have_named_sections)
+  if (! TARGET_HAVE_NAMED_SECTIONS)
     {
       if (flag_function_sections)
 	{
diff -rup orig/egcc-CVS20031230/gcc/tree.c egcc-CVS20031230/gcc/tree.c
--- orig/egcc-CVS20031230/gcc/tree.c	2003-12-20 20:01:08.000000000 -0500
+++ egcc-CVS20031230/gcc/tree.c	2004-01-01 15:40:20.810340000 -0500
@@ -45,6 +45,8 @@ Software Foundation, 59 Temple Place - S
 #include "output.h"
 #include "target.h"
 #include "langhooks.h"
+#include "rtl.h"
+#include "expr.h"
 
 /* obstack.[ch] explicitly declined to prototype this.  */
 extern int _obstack_allocated_p (struct obstack *h, void *obj);
@@ -302,7 +304,7 @@ make_node (enum tree_code code)
 
       /* Default to no attributes for type, but let target change that.  */
       TYPE_ATTRIBUTES (t) = NULL_TREE;
-      (*targetm.set_default_type_attributes) (t);
+      TARGET_SET_DEFAULT_TYPE_ATTRIBUTES (t);
 
       /* We have not yet computed the alias set for this type.  */
       TYPE_ALIAS_SET (t) = -1;
@@ -4924,7 +4926,7 @@ build_common_tree_nodes_2 (int short_dou
   layout_type (complex_long_double_type_node);
 
   {
-    tree t = (*targetm.build_builtin_va_list) ();
+    tree t = TARGET_BUILD_BUILTIN_VA_LIST ();
 
     /* Many back-ends define record types without setting TYPE_NAME.
        If we copied the record type here, we'd keep the original
diff -rup orig/egcc-CVS20031230/gcc/varasm.c egcc-CVS20031230/gcc/varasm.c
--- orig/egcc-CVS20031230/gcc/varasm.c	2003-12-21 20:01:19.000000000 -0500
+++ egcc-CVS20031230/gcc/varasm.c	2004-01-01 14:57:03.616199000 -0500
@@ -397,7 +397,7 @@ named_section_flags (const char *name, u
       if (! set_named_section_flags (name, flags))
 	abort ();
 
-      (*targetm.asm_out.named_section) (name, flags);
+      TARGET_ASM_NAMED_SECTION (name, flags);
 
       if (flags & SECTION_FORGET)
 	in_section = no_section;
@@ -424,7 +424,7 @@ named_section (tree decl, const char *na
   if (name == NULL)
     name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
 
-  flags = (* targetm.section_type_flags) (decl, name, reloc);
+  flags = TARGET_SECTION_TYPE_FLAGS (decl, name, reloc);
 
   /* Sanity check user variables for flag changes.  Non-user
      section flag changes will abort in named_section_flags.
@@ -448,10 +448,10 @@ resolve_unique_section (tree decl, int r
 			int flag_function_or_data_sections)
 {
   if (DECL_SECTION_NAME (decl) == NULL_TREE
-      && targetm.have_named_sections
+      && TARGET_HAVE_NAMED_SECTIONS
       && (flag_function_or_data_sections
 	  || DECL_ONE_ONLY (decl)))
-    (*targetm.asm_out.unique_section) (decl, reloc);
+    TARGET_ASM_UNIQUE_SECTION (decl, reloc);
 }
 
 #ifdef BSS_SECTION_ASM_OP
@@ -487,7 +487,7 @@ asm_output_bss (FILE *file, tree decl AT
 		unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
 		unsigned HOST_WIDE_INT rounded)
 {
-  (*targetm.asm_out.globalize_label) (file, name);
+  TARGET_ASM_GLOBALIZE_LABEL (file, name);
   bss_section ();
 #ifdef ASM_DECLARE_OBJECT_NAME
   last_assemble_variable_decl = decl;
@@ -554,7 +554,7 @@ variable_section (tree decl, int reloc)
   if (IN_NAMED_SECTION (decl))
     named_section (decl, NULL, reloc);
   else
-    (*targetm.asm_out.select_section) (decl, reloc, DECL_ALIGN (decl));
+    TARGET_ASM_SELECT_SECTION (decl, reloc, DECL_ALIGN (decl));
 }
 
 /* Tell assembler to switch to the section for string merging.  */
@@ -782,7 +782,7 @@ make_decl_rtl (tree decl, const char *as
       /* Let the target reassign the RTL if it wants.
 	 This is necessary, for example, when one machine specific
 	 decl attribute overrides another.  */
-      (* targetm.encode_section_info) (decl, DECL_RTL (decl), false);
+      TARGET_ENCODE_SECTION_INFO (decl, DECL_RTL (decl), false);
       return;
     }
 
@@ -882,7 +882,7 @@ make_decl_rtl (tree decl, const char *as
      such as that it is a function name.
      If the name is changed, the macro ASM_OUTPUT_LABELREF
      will have to know how to strip this information.  */
-  (* targetm.encode_section_info) (decl, DECL_RTL (decl), true);
+  TARGET_ENCODE_SECTION_INFO (decl, DECL_RTL (decl), true);
 }
 
 /* Make the rtl for variable VAR be volatile.
@@ -1068,7 +1068,7 @@ notice_global_symbol (tree decl)
       char *name;
       rtx decl_rtl = DECL_RTL (decl);
 
-      p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0));
+      p = TARGET_STRIP_NAME_ENCODING (XSTR (XEXP (decl_rtl, 0), 0));
       name = xstrdup (p);
 
       *type = name;
@@ -1400,7 +1400,7 @@ assemble_variable (tree decl, int top_le
   if (TREE_ASM_WRITTEN (decl))
     return;
 
-  /* Make sure targetm.encode_section_info is invoked before we set
+  /* Make sure TARGET_ENCODE_SECTION_INFO is invoked before we set
      ASM_WRITTEN.  */
   decl_rtl = DECL_RTL (decl);
 
@@ -1665,7 +1665,7 @@ assemble_external_libcall (rtx fun)
   if (! SYMBOL_REF_USED (fun))
     {
       SYMBOL_REF_USED (fun) = 1;
-      (*targetm.asm_out.external_libcall) (fun);
+      TARGET_ASM_EXTERNAL_LIBCALL (fun);
     }
 }
 
@@ -1712,7 +1712,7 @@ assemble_name (FILE *file, const char *n
   const char *real_name;
   tree id;
 
-  real_name = (* targetm.strip_name_encoding) (name);
+  real_name = TARGET_STRIP_NAME_ENCODING (name);
 
   id = maybe_get_identifier (real_name);
   if (id)
@@ -1796,7 +1796,7 @@ assemble_trampoline_template (void)
       ASM_OUTPUT_ALIGN (asm_out_file, align);
     }
 
-  (*targetm.asm_out.internal_label) (asm_out_file, "LTRAMP", 0);
+  TARGET_ASM_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);
   TRAMPOLINE_TEMPLATE (asm_out_file);
 
   /* Record the rtl to refer to it.  */
@@ -1829,25 +1829,30 @@ min_align (unsigned int a, unsigned int 
 const char *
 integer_asm_op (int size, int aligned_p)
 {
-  struct asm_int_op *ops;
-
-  if (aligned_p)
-    ops = &targetm.asm_out.aligned_op;
-  else
-    ops = &targetm.asm_out.unaligned_op;
-
   switch (size)
     {
     case 1:
-      return targetm.asm_out.byte_op;
+      return TARGET_ASM_BYTE_OP;
     case 2:
-      return ops->hi;
+      if (aligned_p)
+	return TARGET_ASM_ALIGNED_HI_OP;
+      else
+	return TARGET_ASM_UNALIGNED_HI_OP;
     case 4:
-      return ops->si;
+      if (aligned_p)
+	return TARGET_ASM_ALIGNED_SI_OP;
+      else
+	return TARGET_ASM_UNALIGNED_SI_OP;
     case 8:
-      return ops->di;
+      if (aligned_p)
+	return TARGET_ASM_ALIGNED_DI_OP;
+      else
+	return TARGET_ASM_UNALIGNED_DI_OP;
     case 16:
-      return ops->ti;
+      if (aligned_p)
+	return TARGET_ASM_ALIGNED_TI_OP;
+      else
+	return TARGET_ASM_UNALIGNED_TI_OP;
     default:
       return NULL;
     }
@@ -1888,7 +1893,7 @@ assemble_integer (rtx x, unsigned int si
   aligned_p = (align >= MIN (size * BITS_PER_UNIT, BIGGEST_ALIGNMENT));
 
   /* See if the target hook can handle this kind of object.  */
-  if ((*targetm.asm_out.integer) (x, size, aligned_p))
+  if (TARGET_ASM_INTEGER (x, size, aligned_p))
     return true;
 
   /* If the object is a multi-byte one, try splitting it up.  Split
@@ -2458,7 +2463,7 @@ build_constant_desc (tree exp)
      information.  This call might invalidate our local variable
      SYMBOL; we can't use it afterward.  */
 
-  (*targetm.encode_section_info) (exp, rtl, true);
+  TARGET_ENCODE_SECTION_INFO (exp, rtl, true);
 
   desc->rtl = rtl;
 
@@ -2561,7 +2566,7 @@ output_constant_def_contents (rtx symbol
   if (IN_NAMED_SECTION (exp))
     named_section (exp, NULL, reloc);
   else
-    (*targetm.asm_out.select_section) (exp, reloc, align);
+    TARGET_ASM_SELECT_SECTION (exp, reloc, align);
 
   if (align > BITS_PER_UNIT)
     {
@@ -2934,7 +2939,7 @@ force_const_mem (enum machine_mode mode,
   unsigned int align;
 
   /* If we're not allowed to drop X into the constant pool, don't.  */
-  if ((*targetm.cannot_force_const_mem) (x))
+  if (TARGET_CANNOT_FORCE_CONST_MEM (x))
     return NULL_RTX;
 
   /* Compute hash code of X.  Search the descriptors for that hash code
@@ -3150,7 +3155,7 @@ output_constant_pool (const char *fnname
 	}
 
       /* First switch to correct section.  */
-      (*targetm.asm_out.select_rtx_section) (pool->mode, x, pool->align);
+      TARGET_ASM_SELECT_RTX_SECTION (pool->mode, x, pool->align);
 
 #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY
       ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, pool->mode,
@@ -3160,7 +3165,7 @@ output_constant_pool (const char *fnname
       assemble_align (pool->align);
 
       /* Output the label.  */
-      (*targetm.asm_out.internal_label) (asm_out_file, "LC", pool->labelno);
+      TARGET_ASM_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
 
       /* Output the value of the constant itself.  */
       switch (GET_MODE_CLASS (pool->mode))
@@ -4378,7 +4383,7 @@ globalize_decl (tree decl)
     }
 #endif
 
-  (*targetm.asm_out.globalize_label) (asm_out_file, name);
+  TARGET_ASM_GLOBALIZE_LABEL (asm_out_file, name);
 }
 
 /* Emit an assembler directive to make the symbol for DECL an alias to
@@ -4461,7 +4466,7 @@ maybe_assemble_visibility (tree decl)
   enum symbol_visibility vis = DECL_VISIBILITY (decl);
 
   if (vis != VISIBILITY_DEFAULT)
-    (* targetm.asm_out.visibility) (decl, vis);
+    TARGET_ASM_ASSEMBLE_VISIBILITY (decl, vis);
 }
 
 /* Returns 1 if the target configuration supports defining public symbols
@@ -4540,7 +4545,7 @@ decl_tls_model (tree decl)
       return kind;
     }
 
-  is_local = (*targetm.binds_local_p) (decl);
+  is_local = TARGET_BINDS_LOCAL_P (decl);
   if (!flag_pic)
     {
       if (is_local)
@@ -4848,11 +4853,11 @@ categorize_decl_for_section (tree decl, 
     }
 
   /* If the target uses small data sections, select it.  */
-  else if ((*targetm.in_small_data_p) (decl))
+  else if (TARGET_IN_SMALL_DATA_P (decl))
     {
       if (ret == SECCAT_BSS)
 	ret = SECCAT_SBSS;
-      else if (targetm.have_srodata_section && ret == SECCAT_RODATA)
+      else if (TARGET_HAVE_SRODATA_SECTION && ret == SECCAT_RODATA)
 	ret = SECCAT_SRODATA;
       else
 	ret = SECCAT_SDATA;
@@ -5016,7 +5021,7 @@ default_unique_section_1 (tree decl, int
   plen = strlen (prefix);
 
   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  name = (* targetm.strip_name_encoding) (name);
+  name = TARGET_STRIP_NAME_ENCODING (name);
   nlen = strlen (name);
 
   string = alloca (nlen + plen + 1);
@@ -5090,9 +5095,9 @@ default_encode_section_info (tree decl, 
   flags = 0;
   if (TREE_CODE (decl) == FUNCTION_DECL)
     flags |= SYMBOL_FLAG_FUNCTION;
-  if ((*targetm.binds_local_p) (decl))
+  if (TARGET_BINDS_LOCAL_P (decl))
     flags |= SYMBOL_FLAG_LOCAL;
-  if ((*targetm.in_small_data_p) (decl))
+  if (TARGET_IN_SMALL_DATA_P (decl))
     flags |= SYMBOL_FLAG_SMALL;
   if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
     flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT;
@@ -5199,10 +5204,10 @@ default_internal_label (FILE *stream, co
 void
 default_file_start (void)
 {
-  if (targetm.file_start_app_off && !flag_verbose_asm)
+  if (TARGET_ASM_FILE_START_APP_OFF && !flag_verbose_asm)
     fputs (ASM_APP_OFF, asm_out_file);
 
-  if (targetm.file_start_file_directive)
+  if (TARGET_ASM_FILE_START_FILE_DIRECTIVE)
     output_file_directive (asm_out_file, main_input_filename);
 }
 
diff -rup orig/egcc-CVS20031230/gcc/vmsdbgout.c egcc-CVS20031230/gcc/vmsdbgout.c
--- orig/egcc-CVS20031230/gcc/vmsdbgout.c	2003-07-19 10:42:23.000000000 -0400
+++ egcc-CVS20031230/gcc/vmsdbgout.c	2004-01-01 14:57:39.763545000 -0500
@@ -1320,7 +1320,7 @@ vmsdbgout_begin_block (register unsigned
     (*dwarf2_debug_hooks.begin_block) (line, blocknum);
 
   if (debug_info_level > DINFO_LEVEL_TERSE)
-    (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
+    TARGET_ASM_INTERNAL_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
 }
 
 /* Output a marker (i.e. a label) for the end of the generated code for a
@@ -1333,7 +1333,7 @@ vmsdbgout_end_block (register unsigned l
     (*dwarf2_debug_hooks.end_block) (line, blocknum);
 
   if (debug_info_level > DINFO_LEVEL_TERSE)
-    (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_END_LABEL, blocknum);
+    TARGET_ASM_INTERNAL_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
 }
 
 /* Not implemented in VMS Debug.  */
@@ -1513,7 +1513,7 @@ vmsdbgout_source_line (register unsigned
     {
       dst_line_info_ref line_info;
 
-      (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
+      TARGET_ASM_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
 				 line_info_table_in_use);
 
       /* Expand the line info table if necessary.  */
@@ -1670,7 +1670,7 @@ vmsdbgout_finish (const char *main_input
 
   /* Output a terminator label for the .text section.  */
   text_section ();
-  (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
+  TARGET_ASM_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
 
   /* Output debugging information.
      Warning! Do not change the name of the .vmsdebug section without

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18  8:37 Ian Lance Taylor
  2004-01-18  9:03 ` Zack Weinberg
@ 2004-01-18 11:30 ` Joseph S. Myers
  2004-01-18 13:58 ` Kaveh R. Ghazi
  2004-01-19  1:12 ` Geoff Keating
  3 siblings, 0 replies; 45+ messages in thread
From: Joseph S. Myers @ 2004-01-18 11:30 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

On Sun, 18 Jan 2004, Ian Lance Taylor wrote:

> Somebody must have noticed this before, but I couldn't find anything
> in the gcc mailing list.

I queried the performance cost when Zack proposed moving the macros for
type sizes to the target structure
<http://gcc.gnu.org/ml/gcc/2003-07/msg01615.html>, but without any
benchmark figures.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

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

* Re: Can we speed up the gcc_target structure?
  2004-01-18  8:37 Ian Lance Taylor
@ 2004-01-18  9:03 ` Zack Weinberg
  2004-01-18 14:09   ` Ian Lance Taylor
  2004-01-18 11:30 ` Joseph S. Myers
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 45+ messages in thread
From: Zack Weinberg @ 2004-01-18  9:03 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Ian Lance Taylor <ian@wasabisystems.com> writes:

> Back in the old days, gcc had a lot of code which was conditionally
> compiled with #ifdef.  That was ugly, but the resulting code was fast.
> Over time, a lot of the parameters checked with #ifdef were converted
> into macros which were checked at runtime using if.  That was less
> ugly, and, since the macros normally had constant values, when gcc was
> compiled with an optimizing compiler, the code was just as fast in the
> normal case.  When it was slower, it was generally because the
> compiler was doing something it couldn't do before.
[...]

Any change along these lines loses what I think is a critical property
of the target vector, which is that modifications to the target-specific
code on the far side of it do *not* require recompilation of the
entire machine-independent compiler.

I consider it a desirable and achievable goal to be able to swap out
the entire back end without rebuilding any of the optimizers; this
entails having *everything* go through the target vector or some other
sort of link-time interface.  (For instance, I see no need to change
the way recog.c interacts with insn-recog.c for this purpose.)

Furthermore, while a 3% measured speed hit is a concern, I think that
trying to win it back by undoing the targetm transformation - in the
object files, if not in the source code - is barking up the wrong
tree.  Instead we should be looking for ways to avoid having targetm
hooks in critical paths in the first place.  It's been my experience
that that is a much more fruitful source of optimization
opportunities.

zw

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

* Can we speed up the gcc_target structure?
@ 2004-01-18  8:37 Ian Lance Taylor
  2004-01-18  9:03 ` Zack Weinberg
                   ` (3 more replies)
  0 siblings, 4 replies; 45+ messages in thread
From: Ian Lance Taylor @ 2004-01-18  8:37 UTC (permalink / raw)
  To: gcc

Back in the old days, gcc had a lot of code which was conditionally
compiled with #ifdef.  That was ugly, but the resulting code was fast.
Over time, a lot of the parameters checked with #ifdef were converted
into macros which were checked at runtime using if.  That was less
ugly, and, since the macros normally had constant values, when gcc was
compiled with an optimizing compiler, the code was just as fast in the
normal case.  When it was slower, it was generally because the
compiler was doing something it couldn't do before.

More recently, some of those parameters have moved into the gcc_target
structure.  They are still checked at run time, but now the if
condition never has a constant value.  It always requires fetching a
value from memory in the target vector, and often requires calling a
function.  This results in cleaner, more comprehensible code.

However, it also slows the compiler down.

Just for fun, I converted every instance of
    targetm.calls.xxxx
to be
    TARGETM_CALLS_XXXX
instead.  Then I added stuff like this to the end of target.h:

#ifndef TARGETM_CALLS_PROMOTE_FUNCTION_ARGS
#define TARGETM_CALLS_PROMOTE_FUNCTION_ARGS(FNTYPE) \
  targetm.calls.promote_function_args ((FNTYPE))
#endif

Then I added stuff like this to i386.h:

#define TARGETM_CALLS_PROMOTE_FUNCTION_ARGS(FNTYPE) false

Then I rebuilt the compiler and tried it on some reasonably small C++
example (with a native i386 GNU/Linux compiler).  I saw compilation
speedups of up to 3% when compiling without optimization.  The
resulting assembler output was, as expected, identical.

These tests were far from rigorous.  However, compilation speed is a
concern these days, and this suggests that the target vector is a
measurable speed problem.

Somebody must have noticed this before, but I couldn't find anything
in the gcc mailing list.

It seems to me that we should try to find a way to regain the speed
which was lost when we switched to the target vector, without losing
the comprehensibility which was gained.

Here is a sketch of a possible approach which would require fairly
minimal changes in the way the target vector works today:

1) Turn hooks.c and targhooks.c into .h files which define inline
   functions (with appropriate fallbacks to support older non-gcc
   compilers for bootstrapping, of course).

2) Move all definitions of target initializer macros from tm.c files
   into new CPU-target.h files.

3) Include CPU-target.h at the end of target-def.h, where it will
   redefine and undefine target initializer macros.  For cases in
   which targetm is changed at run time, CPU-target.h must #undef the
   corresponding initializer macro (and CPU.c must #define it before
   initializing targetm) (alternatively, force targetm to be const,
   and adjust the relatively few cases in which it is changed at run
   time).

4) Change all uses of targetm.xxxx into code which uses TARGETM_XXXX
   macros, as above.

5) Define the TARGETM macros as either using the target vector or
   using the initializer macro from target-def.h.  The choice would be
   made based on whether the initializer macro was defined and
   probably based on some other control.

6) Now code which uses the new inline versions of hooks.c and
   targhooks.c, and which includes target-def.h and CPU-target.h, will
   automatically use the inlined versions of the functions when
   possible, and will see constant variable definitions when possible.

The main problem that I see with this approach is the requirement to
#undef an initializer macro which is changed at run time.  That's why
I suggest the alternative of making targetm const.

We can convert to this approach over time if we require a particular
macro to be defined in order to define the TARGETM macros as using the
initializer macros rather than the target vector.  Then a backend
which has been converted to use CPU-target.h would define that macro.

If we eventually want to configure gcc to support multiple target
vectors, that would still be possible.  When more than one target
vector was to be supported, the code would force the TARGETM macros to
always use the target vector.  This would be determined at configure
time.

I considered more complex approaches, such as creating a target.def
file which defined the target vector, but the basic problem boils down
to detecting when the target does not use the default version of a
target vector field.  Inventing CPU-target.h seems as effective an
approach as any to solving this particular problem.

Any thoughts?  Does anybody think this would be a waste of time?  Does
anybody have a better approach to solving the general problem?

Ian

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

end of thread, other threads:[~2004-01-19 23:48 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-19 23:42 Can we speed up the gcc_target structure? Richard Kenner
2004-01-19 23:46 ` Zack Weinberg
  -- strict thread matches above, loose matches on Subject: below --
2004-01-19 23:48 Richard Kenner
2004-01-19 21:25 Richard Kenner
2004-01-19 23:36 ` Zack Weinberg
2004-01-19 19:05 Richard Kenner
2004-01-19 21:15 ` Zack Weinberg
2004-01-19 18:18 Richard Kenner
2004-01-19 18:26 ` Zack Weinberg
2004-01-19 11:51 Richard Kenner
2004-01-19 12:01 ` Richard Guenther
2004-01-19 20:02   ` Richard Henderson
2004-01-19 14:16 ` Robert Dewar
2004-01-19 18:03 ` Zack Weinberg
2004-01-18 22:18 Chris Lattner
2004-01-18 22:33 ` Jan Hubicka
2004-01-18 22:40   ` Chris Lattner
2004-01-18 22:48     ` Jan Hubicka
2004-01-18 22:50       ` Chris Lattner
2004-01-18 23:27         ` Jan Hubicka
2004-01-18 23:34           ` Jakub Jelinek
2004-01-19  1:36           ` Chris Lattner
2004-01-18 22:42   ` Joseph S. Myers
2004-01-18 22:44     ` Chris Lattner
2004-01-18 22:36 ` Richard Henderson
2004-01-18 22:42   ` Chris Lattner
2004-01-18  8:37 Ian Lance Taylor
2004-01-18  9:03 ` Zack Weinberg
2004-01-18 14:09   ` Ian Lance Taylor
2004-01-18 22:25     ` Zack Weinberg
2004-01-19  0:53       ` Ian Lance Taylor
2004-01-19  1:18       ` Geoff Keating
2004-01-18 11:30 ` Joseph S. Myers
2004-01-18 13:58 ` Kaveh R. Ghazi
2004-01-18 19:54   ` Ian Lance Taylor
2004-01-18 20:10     ` Richard Henderson
2004-01-18 20:17       ` Ian Lance Taylor
2004-01-18 21:14   ` Joseph S. Myers
2004-01-18 22:05     ` Richard Henderson
2004-01-18 22:22       ` Jan Hubicka
2004-01-18 22:37         ` Richard Henderson
2004-01-19 19:33           ` DJ Delorie
2004-01-19 20:41             ` Richard Henderson
2004-01-19  1:12 ` Geoff Keating
2004-01-19 13:51   ` Ian Lance Taylor

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