Message ID | 20100624150200.roql5i8jkwo8sk88-nzlynne@webmail.spamcop.net |
---|---|
State | New |
Headers | show |
On Thu, Jun 24, 2010 at 9:02 PM, Joern Rennecke <amylaar@spamcop.net> wrote: > This fixes up the uses of crtl->args.info . > > Bootstrapped and regression tested on i686-pc-linux-gnu in revision 161310. > > There is still an issue with all the target hooks that have CUMULATIVE_ARGS > parameters. This could either be fixed up by changing the function > paraemter > types in very port - which would be a very large patch Nathan, didn't you promise a patch for this?? ;-) Ciao! Steven
Quoting Steven Bosscher <stevenb.gcc@gmail.com>: > On Thu, Jun 24, 2010 at 9:02 PM, Joern Rennecke <amylaar@spamcop.net> wrote: >> This fixes up the uses of crtl->args.info . >> >> Bootstrapped and regression tested on i686-pc-linux-gnu in revision 161310. >> >> There is still an issue with all the target hooks that have CUMULATIVE_ARGS >> parameters. This could either be fixed up by changing the function >> paraemter >> types in very port - which would be a very large patch > > Nathan, didn't you promise a patch for this?? ;-) This irony is that everything works just fine with the old-style target macros wrapped into target hooks in targhooks.c : A single change to the targhooks.c implementation fixes the interface. However, with target hook directly implemented in tm.c, each tm.c has to be fixed. Unless we go the route of adding another wrapper function.
On Thu, Jun 24, 2010 at 09:18:05PM +0200, Steven Bosscher wrote: > On Thu, Jun 24, 2010 at 9:02 PM, Joern Rennecke <amylaar@spamcop.net> wrote: > > This fixes up the uses of crtl->args.info . > > > > There is still an issue with all the target hooks that have CUMULATIVE_ARGS > > parameters. This could either be fixed up by changing the function > > paraemter > > types in very port - which would be a very large patch > > Nathan, didn't you promise a patch for this?? ;-) I don't know if "promise" is the right word, but I certainly have it in my TODO list. The grand plan (I was waiting until I had a patch to talk about this, but since you asked...), looks something like this: - Hookize FUNCTION_ARG &co. (patch approved, I need to reassure myself that some of the const-ization in the patch isn't going to break bootstrap and commit) - Hookize INIT_CUMULATIVE_ARGS &co. INIT_CUMULATIVE_ARGS is the big one; I plan to convert it to something with prototype: CUMULATIVE_ARGS *target_init_cum_args (fntype, libname, fndecl, n_named); Other hooks (INIT_CUMULATIVE_INCOMING_ARGS, for instance) will be changed similarly to return a CUMULATIVE_ARGS *. See below for discussion of problem with this approach. - Convert all backends (big patch, but can be done incrementally. I have private patches for the FUNCTION_ARG &co. hookization.) - At this point, the non-backend portions of the compiler only deal with CUMULATIVE_ARGS through pointers; there are no direct references. It's possible there are other bits I am missing here, because I'm not familiar with this portion of the compiler. Repeat above steps as necessary for hooks that I have failed to lookup and other bits. - In one fell swoop, s/CUMULATIVE_ARGS/struct cumulative_args/ in the non-backend portions of the compiler. Do the same in the backends, moving the actual definition of 'struct cumulative_args' into the backends's .c files, rather than the headers. This is one place where C++ and virtual functions would be useful; the target hooks dealing with CUMULATIVE_ARGS, I think, should really be methods on a CUMULATIVE_ARGS class. (Depending on the target, this might enable removing some overhead with complicated argument passing that varies with the subarchitecture.) There is one small problem with the above plan (that I am aware of; perhaps there are others that I am not aware of, and I would welcome pointers to them): what to do with managing the 'CUMULATIVE_ARGS *' returned by the backend? I think the options are: - Have every backend return a pointer to statically allocated memory. This is the easiest thing to do, but also likely to blow up for weird uses of CUMULATIVE_ARGS. No need to free or equivalent. This is what I was going to do. - Allocate it in the backend hook. Presumably we want to dictate the method of allocation so we don't need to add *another* hook for deallocating. obstacks, xmalloc, whatever. I don't have an opinion here. If people think something like the above plan is the way to go, it's not clear to me that Joern's patch is a step forward, since INCOMING_ARGS_INFO will just be bitrotten after the above plan lands on trunk. Comments? Criticisms? Bets on whether this can be done before the end of stage 1? :) -Nathan
Quoting Nathan Froyd <froydnj@codesourcery.com>: > The grand plan (I was waiting until I had a patch to talk about this, > but since you asked...), looks something like this: > > - Hookize FUNCTION_ARG &co. (patch approved, I need to reassure myself > that some of the const-ization in the patch isn't going to break > bootstrap and commit) > > - Hookize INIT_CUMULATIVE_ARGS &co. INIT_CUMULATIVE_ARGS is the big > one; I plan to convert it to something with prototype: > > CUMULATIVE_ARGS *target_init_cum_args (fntype, libname, fndecl, n_named); This is wrong, because CUMULATIVE_ARGS is a target dependent type, so it makes the target vector type useless to handle more than one target. Either use a void* which is casted appropriately, or a pointer to a union. You can see in multi-target-20100622-branch how multiple configured targets can get separate union fields assigned. The build machinery there creates the INCOMING_ARGS_INFO accessor macros. The patch at the start of this thread contains the code for the case of configuring for only a single target; this could be straightforwardly extended to more macros if you want different names or ways to place the union tag. > This is one place where C++ and virtual functions would be useful; the > target hooks dealing with CUMULATIVE_ARGS, I think, should really be > methods on a CUMULATIVE_ARGS class. (Depending on the target, this > might enable removing some overhead with complicated argument passing > that varies with the subarchitecture.) But that would be a class that is different for every target, so again it is not suitable to appear in the target hooks. What you could do is to have a base class without class data, which has these target methods, and then have the targets define target-specific derived CUMULATIVE_ARGS classes, and have their target hooks expect that the pointers point to an object of its own derived class. > There is one small problem with the above plan (that I am aware of; > perhaps there are others that I am not aware of, and I would welcome > pointers to them): what to do with managing the 'CUMULATIVE_ARGS *' > returned by the backend? I think the options are: > > - Have every backend return a pointer to statically allocated memory. > This is the easiest thing to do, but also likely to blow up for weird > uses of CUMULATIVE_ARGS. No need to free or equivalent. This is what > I was going to do. If we later want to go multi-threaded, that would have to become thread-specific, i.e. often expensive. The current scheme where the caller allocates the memory is really better. Typically the data is wanted as a local variable on the stack. And as I have demonstrated, we can figure out the maximum amount of memory that any target's CUMULATIVE_ARG needs, so that we can allocate a cumulative_args_u in the caller. Or for C++, when you create a base class for all CUMULATIVE_ARGS types, you can have a member in cumulative_args_u which is of that type, so that you can easily get a pointer to that. > - Allocate it in the backend hook. Presumably we want to dictate the > method of allocation so we don't need to add *another* hook for > deallocating. obstacks, xmalloc, whatever. I don't have an opinion > here. > > If people think something like the above plan is the way to go, it's not > clear to me that Joern's patch is a step forward, since > INCOMING_ARGS_INFO will just be bitrotten after the above plan lands on > trunk. INCOMING_ARGS_INFO is needed in lots of contexts: E.g. in May last year I found this for the SH: * config/sh/sh.c (calc_live_regs): Use INCOMING_ARGS_INFO. (sh_expand_prologue, sh_expand_epilogue): Likewise. (sh_builtin_saveregs, sh_va_start): Likewise. (initial_elimination_offset, sh_allocate_initial_value): Likewise. (sh_function_ok_for_sibcall): Likewise. * config/sh/sh.md (return, return_i): Likewise. (shcompact_return_tramp, shcompact_return_tramp_i): Likewise.
[Thread renamed like I should have done last night. Whoops!] On Thu, Jun 24, 2010 at 11:16:29PM -0400, Joern Rennecke wrote: > Quoting Nathan Froyd <froydnj@codesourcery.com>: >> - Hookize INIT_CUMULATIVE_ARGS &co. INIT_CUMULATIVE_ARGS is the big >> one; I plan to convert it to something with prototype: >> >> CUMULATIVE_ARGS *target_init_cum_args (fntype, libname, fndecl, n_named); > > This is wrong, because CUMULATIVE_ARGS is a target dependent type, so it makes > the target vector type useless to handle more than one target. > Either use a void* which is casted appropriately, or a pointer to a > union. I do not understand the relevance of this comment. I agree that CUMULATIVE_ARGS is a target dependent type. The plan that I posted is about removing the exposure of CUMULATIVE_ARGS to the non-backend portions of the compiler. The above step is one step along the way. A later step converts this returning of 'CUMULATIVE_ARGS *' to 'struct cumulative_args *'; a forward declaration of 'struct cumulative_args' can be provided in an appropriate header file. If people are happier with 'void *', that's fine too. I was aiming for slightly self-documenting code. >> This is one place where C++ and virtual functions would be useful; the >> target hooks dealing with CUMULATIVE_ARGS, I think, should really be >> methods on a CUMULATIVE_ARGS class. (Depending on the target, this >> might enable removing some overhead with complicated argument passing >> that varies with the subarchitecture.) > > What you could do is to have a base class without class data, which has these > target methods, and then have the targets define target-specific derived > CUMULATIVE_ARGS classes, and have their target hooks expect that the pointers > point to an object of its own derived class. Yes, that was the plan. My apologies if the intent was not clear. >> There is one small problem with the above plan (that I am aware of; >> perhaps there are others that I am not aware of, and I would welcome >> pointers to them): what to do with managing the 'CUMULATIVE_ARGS *' >> returned by the backend? I think the options are: >> >> - Have every backend return a pointer to statically allocated memory. >> This is the easiest thing to do, but also likely to blow up for weird >> uses of CUMULATIVE_ARGS. No need to free or equivalent. This is what >> I was going to do. > > If we later want to go multi-threaded, that would have to become > thread-specific, i.e. often expensive. I think that a multi-threaded gcc is a *long* way off. If we did ever get to that point, one thread-specific variable and the cost of its accesses would be the least of our problems. -Nathan
Quoting Nathan Froyd <froydnj@codesourcery.com>: > I do not understand the relevance of this comment. I agree that > CUMULATIVE_ARGS is a target dependent type. The plan that I posted is > about removing the exposure of CUMULATIVE_ARGS to the non-backend > portions of the compiler. The problem is that when CUMULATIVE_ARGS becomes (more entrenched as) part of the target hook interface, you'll have some 40 places for each hook in the config files that need to be fixed to remove that target-dependence from the target vector again. That's a lot more work than doing anything to the call site. > The above step is one step along the way. A > later step converts this returning of 'CUMULATIVE_ARGS *' to 'struct > cumulative_args *'; a forward declaration of 'struct cumulative_args' > can be provided in an appropriate header file. If people are happier > with 'void *', that's fine too. I was aiming for slightly > self-documenting code. You can use a define or typedef to make that void * more self-documenting. In fact I was thinking the other day that that's what I should do with the enum reg_class -> int conversion too. That should also make it easier if we later find a better way of doing thing by some clever use of classes, or for register classes, if we get to use any new language feature that allows to have an int for the interface but treat it as passing / receiving an enum for type check purposes. So if you do a #define CUMULATIVE_ARGS_U CUMULATIVE_ARGS and then use that in the target hook interface, and in the target hooks, and cast between CUMULATIVE_ARGS_U * and CUMULATIVE_ARGS * as appropriate, only the define would need to be changed to remove the target-dependency from the target vector. > I think that a multi-threaded gcc is a *long* way off. I don't think it needs to be that far off. So far, there was little demand for it, because make -j works so well. That will no longer be that case with lto. At the same time, we see the number of cores and available simultaneously executed threads in workstation / server class machines rising. We might not want to care about all the details of handling multithreading, but being able to apply some OMP directives to leverage GOMP might already give some nice speedups, plus it's a matter of eating our own dog food, so to speak. > If we did ever > get to that point, one thread-specific variable and the cost of its > accesses would be the least of our problems. I think it is important to keep future requirements in mind when we have some choice when doing a design decision. At the moment the cost of selecting different paths is low; it's going to be much more expensive to switch later. It's not the number of variables that matters so much as the number of variable accesses during a compilation. For typical C code (as compilation workload for gcc) CUMULATIVE_ARGS accesses are probably not that important, as we don't process function calls that often. For C++ with lots of small member functions I would expect that to be a little more. But more importantly, once a particular way of doing things is established in one place in GCC, it has a tendency to spread to other places where analogous problems are encountered.
On Fri, Jun 25, 2010 at 08:30:25AM -0400, Joern Rennecke wrote: > Quoting Nathan Froyd <froydnj@codesourcery.com>: > >> I do not understand the relevance of this comment. I agree that >> CUMULATIVE_ARGS is a target dependent type. The plan that I posted is >> about removing the exposure of CUMULATIVE_ARGS to the non-backend >> portions of the compiler. > > The problem is that when CUMULATIVE_ARGS becomes (more entrenched as) > part of the target hook interface, you'll have some 40 places for each > hook in the config files that need to be fixed to remove that > target-dependence from the target vector again. That's a lot more work > than doing anything to the call site. I don't understand the argument here. How is moving around CUMULATIVE_ARGS in the target hook interface making it "more entrenched"? Converting all references to CUMULATIVE_ARGS to use pointers is actually making things less entrenched, because then the layout of CUMULATIVE_ARGS need not be exposed to the non-backend portions of the compiler. >> I think that a multi-threaded gcc is a *long* way off. > > I don't think it needs to be that far off. So far, there was little demand > for it, because make -j works so well. That will no longer be that case > with lto. WHOPR and friends effectively apply make -j to LTO compilations, so the benefits of multi-threading go down substantially. >> If we did ever >> get to that point, one thread-specific variable and the cost of its >> accesses would be the least of our problems. > > It's not the number of variables that matters so much as the number of > variable accesses during a compilation. For typical C code (as compilation > workload for gcc) CUMULATIVE_ARGS accesses are probably not that important, > as we don't process function calls that often. For C++ with lots of small > member functions I would expect that to be a little more. The accesses we are talking about here are the cost of computing the address of the thread-local variable once in the TARGET_INIT_CUMULATIVE_ARGS hook. Before multi-threading: static void * ix86_init_cumulative_args (blah_blah) { static struct ix86_cumulative_args ca; /* init CA */ return &ca; } After multi-threading: static void * ix86_init_cumulative_args (blah_blah) { static __thread struct ix86_cumulative_args ca; /* I don't know if the compiler is able to optimize: ca.foo = x; ca.bar = y; to compute the address of CA only once. If so, this bit could go away. */ struct ix86_cumulative_args *pca = &ca; /* init PCA */ return pca; } Doing this is not particularly expensive, even if computing the address requires several thousand cycles. Querying and setting members of PCA, as would happen in other target hooks, runs at full speed. All those small members functions are likely to get inlined anyway, so we'll never generate out-of-line code for them. -Nathan
Quoting Nathan Froyd <froydnj@codesourcery.com>: > I don't understand the argument here. How is moving around > CUMULATIVE_ARGS in the target hook interface making it "more > entrenched"? Converting all references to CUMULATIVE_ARGS to use > pointers is actually making things less entrenched, because then the > layout of CUMULATIVE_ARGS need not be exposed to the non-backend > portions of the compiler. That's a misunderstanding then. No, changing from CUMULATIVE_ARGS to CUMULATIVE_ARGS * does not create any new problems (as long as you don't have any arrays / pointer-arithmetic (e.g. increment) on these pointers). I meant you increase the problem when you increase the number of target hooks that use CUMULATIVE_ARGS, or increase the number of their implementations in the various config/*/* files.
On Fri, Jun 25, 2010 at 10:15:39AM -0400, Joern Rennecke wrote: > Quoting Nathan Froyd <froydnj@codesourcery.com>: > >> I don't understand the argument here. How is moving around >> CUMULATIVE_ARGS in the target hook interface making it "more >> entrenched"? Converting all references to CUMULATIVE_ARGS to use >> pointers is actually making things less entrenched, because then the >> layout of CUMULATIVE_ARGS need not be exposed to the non-backend >> portions of the compiler. > > That's a misunderstanding then. No, changing from CUMULATIVE_ARGS to > CUMULATIVE_ARGS * does not create any new problems (as long as you don't > have any arrays / pointer-arithmetic (e.g. increment) on these pointers). > I meant you increase the problem when you increase the number of target > hooks that use CUMULATIVE_ARGS, or increase the number of their > implementations in the various config/*/* files. But you're not increasing the number of points that use CUMULATIVE_ARGS. If you have a target macro that uses CUMULATIVE_ARGS, and you change that to a target hook that uses CUMULATIVE_ARGS *, you haven't changed the number of points in the backend that deal with it. I don't see how moving the implementation of CUMULATIVE_ARGS-using bits from config/$ARCH/$ARCH.h to config/$ARCH/$ARCH.c is contributing to further entrenchment. It's making things better because of the above layout concern and because you don't have random backend bits being stuck into the middle-end via macros. -Nathan
Quoting Nathan Froyd <froydnj@codesourcery.com>: > But you're not increasing the number of points that use CUMULATIVE_ARGS. > If you have a target macro that uses CUMULATIVE_ARGS, and you change > that to a target hook that uses CUMULATIVE_ARGS *, you haven't changed > the number of points in the backend that deal with it. I don't see how > moving the implementation of CUMULATIVE_ARGS-using bits from > config/$ARCH/$ARCH.h to config/$ARCH/$ARCH.c is contributing to further > entrenchment. targhooks.c is compiled once for every target. But I have to change its source code only once to change the interface, no matter what target macros it uses inside. Likewise, other code in the compiler that depends on target macros gets compiled separately for each target. The target vector is supposed to isulate the middle-end from target dependencies; if its interface becomes target-dependent, that makes it useless for that purpose.
On Fri, Jun 25, 2010 at 01:37:21PM -0400, Joern Rennecke wrote: > targhooks.c is compiled once for every target. But I have to change its > source code only once to change the interface, no matter what target > macros it uses inside. Likewise, other code in the compiler that depends > on target macros gets compiled separately for each target. > > The target vector is supposed to isulate the middle-end from target > dependencies; if its interface becomes target-dependent, that makes > it useless for that purpose. Yes, we agree here, but I must be dense, because I can't tell what changes that you think I would make that make it target-dependent. Could you please provide examples of such changes? Just for clarification: I'm talking about making hooks that take/return pointers to CUMULATIVE_ARGS, *not* the actual CUMULATIVE_ARGS structure. -Nathan
Quoting Nathan Froyd <froydnj@codesourcery.com>: > Yes, we agree here, but I must be dense, because I can't tell what > changes that you think I would make that make it target-dependent. > Could you please provide examples of such changes? Just for > clarification: I'm talking about making hooks that take/return pointers > to CUMULATIVE_ARGS, *not* the actual CUMULATIVE_ARGS structure. If you declare it as CUMULATIVE_ARGS *, then alias analysis is entitled to think that this can't be anything but the CUMULATIVE_ARGS that it is currently seeing. A compiler is even entitled to have different kinds of pointers dependent on the data type pointed to - although gcc doesn't do this (for now?). If you declare it as void * - or something typedef'ed to void * - than this problem does not arise.
On Fri, Jun 25, 2010 at 02:05:26PM -0400, Joern Rennecke wrote: > Quoting Nathan Froyd <froydnj@codesourcery.com>: >> Yes, we agree here, but I must be dense, because I can't tell what >> changes that you think I would make that make it target-dependent. >> Could you please provide examples of such changes? Just for >> clarification: I'm talking about making hooks that take/return pointers >> to CUMULATIVE_ARGS, *not* the actual CUMULATIVE_ARGS structure. > > If you declare it as void * - or something typedef'ed to void * - than this > problem does not arise. OK, great. This can be done after (or concurrently with) the last step of the grand plan posted above. I don't think it's worth doing something with 'void *' until things are hookized appropriately. Once the hookization is complete, I agree that it would be reasonable to use 'void *' or similar to ensure the compiler does not perform unexpected optimizations and to guard against errant pointer arithmetic. -Nathan
Quoting Joern Rennecke <amylaar@spamcop.net>: + ) >> tmp-target-gtypes.h That was supposed to read '>'. Likewise in the patch for RTL_ASM_CLOBBERS, except that when you reassemble the pieces again, it goes back to '>>'.
Quoting Nathan Froyd <froydnj@codesourcery.com>: > The grand plan (I was waiting until I had a patch to talk about this, > but since you asked...), looks something like this: > > - Hookize FUNCTION_ARG &co. (patch approved, I need to reassure myself > that some of the const-ization in the patch isn't going to break > bootstrap and commit) > > - Hookize INIT_CUMULATIVE_ARGS &co. INIT_CUMULATIVE_ARGS is the big > one; I plan to convert it to something with prototype: > > CUMULATIVE_ARGS *target_init_cum_args (fntype, libname, fndecl, n_named); As has been discussed in the meantime, we need a target-independent, opaque type for the hook interface, which can be cumulative_args_t, typedefed to a struct or union pointer, and converted from/to the target specific type in a pair of small inline functions. > > Other hooks (INIT_CUMULATIVE_INCOMING_ARGS, for instance) will be > changed similarly to return a CUMULATIVE_ARGS *. See below for > discussion of problem with this approach. > > - Convert all backends (big patch, but can be done incrementally. I > have private patches for the FUNCTION_ARG &co. hookization.) > > - At this point, the non-backend portions of the compiler only deal with > CUMULATIVE_ARGS through pointers; there are no direct references. > > It's possible there are other bits I am missing here, because I'm not > familiar with this portion of the compiler. Repeat above steps as > necessary for hooks that I have failed to lookup and other bits. > > - In one fell swoop, s/CUMULATIVE_ARGS/struct cumulative_args/ in the > non-backend portions of the compiler. Do the same in the backends, > moving the actual definition of 'struct cumulative_args' into the > backends's .c files, rather than the headers. > > This is one place where C++ and virtual functions would be useful; the > target hooks dealing with CUMULATIVE_ARGS, I think, should really be > methods on a CUMULATIVE_ARGS class. (Depending on the target, this > might enable removing some overhead with complicated argument passing > that varies with the subarchitecture.) > > There is one small problem with the above plan (that I am aware of; > perhaps there are others that I am not aware of, and I would welcome > pointers to them): what to do with managing the 'CUMULATIVE_ARGS *' > returned by the backend? I think the options are: > > - Have every backend return a pointer to statically allocated memory. > This is the easiest thing to do, but also likely to blow up for weird > uses of CUMULATIVE_ARGS. No need to free or equivalent. This is what > I was going to do. That will be most efficient for the majority us uses, and thus should be supported. > > - Allocate it in the backend hook. Presumably we want to dictate the > method of allocation so we don't need to add *another* hook for > deallocating. obstacks, xmalloc, whatever. I don't have an opinion > here. The problem is that that this doesn't allow you to use even alloca, so you'd need a high-overhead allocation function. I think it is better to have a piece-of-data target "hook" for the size to allocate for a cumulative_args_t. Then the init_cumulative_args hook takes a void * argument for the allocated memory. Targets that are fine with the statically allocated scheme can pass in NULL. > > If people think something like the above plan is the way to go, it's not > clear to me that Joern's patch is a step forward, since > INCOMING_ARGS_INFO will just be bitrotten after the above plan lands on > trunk. > > Comments? Criticisms? Bets on whether this can be done before the end > of stage 1? :) > > -Nathan >
Index: gcc/target.h =================================================================== --- gcc/target.h (revision 161310) +++ gcc/target.h (working copy) @@ -976,6 +976,10 @@ struct gcc_target bool (*return_in_memory) (const_tree type, const_tree fndecl); bool (*return_in_msb) (const_tree type); + /* ??? FIXME: we shouldn't use CUMULATIVE_ARGS in the target hook + interface, here, because this is a target dependent type. + We should use union cumulative_args_u instead. */ + /* Return true if a parameter must be passed by reference. TYPE may be null if this is a libcall. CA may be null if this query is from __builtin_va_arg. */ Index: gcc/function.c =================================================================== --- gcc/function.c (revision 161310) +++ gcc/function.c (working copy) @@ -3375,7 +3375,7 @@ assign_parms (tree fndecl) /* For stdarg.h function, save info about regs and stack space used by the named args. */ - crtl->args.info = all.args_so_far; + INCOMING_ARGS_INFO (crtl->args) = all.args_so_far; /* Set the rtx used for the function return value. Put this in its own variable so any optimizers that need this information don't have Index: gcc/function.h =================================================================== --- gcc/function.h (revision 161310) +++ gcc/function.h (working copy) @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. #include "vecprim.h" #include "tm.h" /* For CUMULATIVE_ARGS. */ #include "hard-reg-set.h" +#include "target-gtypes.h" /* Stack of pending (incomplete) sequences saved by `start_sequence'. Each element describes one pending sequence. @@ -210,12 +211,14 @@ struct GTY(()) incoming_args { /* Quantities of various kinds of registers used for the current function's args. */ - CUMULATIVE_ARGS info; + cumulative_args_u GTY ((desc ("cfun ? cfun->target_arch : -1"))) info; /* The arg pointer hard register, or the pseudo into which it was copied. */ rtx internal_arg_pointer; }; +#define INCOMING_ARGS_INFO(INCOMING_ARGS) ((INCOMING_ARGS).info._ca) + /* Data for function partitioning. */ struct GTY(()) function_subsections { /* Assembly labels for the hot and cold text sections, to @@ -607,6 +610,9 @@ struct GTY(()) function { adjusts one of its arguments and forwards to another function. */ unsigned int is_thunk : 1; + + /* Target architecture to compile this function for. */ + unsigned int target_arch : 8; }; /* If va_list_[gf]pr_size is set to this, it means we don't know how Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 161310) +++ gcc/Makefile.in (working copy) @@ -800,6 +800,9 @@ T = T_TARGET = T_TARGET : $(T_TARGET) +# For building rtl pases for extra target architectures. +TARGET_NUM=0 + # This should name the specs file that we're going to install. Target # Makefiles may override it and name another file to be generated from # the built-in specs and installed as the default spec, as long as @@ -1668,7 +1671,9 @@ cs-tconfig.h: Makefile cs-tm.h: Makefile TARGET_CPU_DEFAULT="$(target_cpu_default)" \ - HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \ + HEADERS="$(tm_include_list)" \ + DEFINES="TARGET_NUM=$(TARGET_NUM) \ + $(tm_defines)" \ $(SHELL) $(srcdir)/mkconfig.sh tm.h cs-tm_p.h: Makefile @@ -3671,7 +3676,7 @@ s-constrs-h: $(MD_DEPS) build/genpreds$( GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/vecprim.h $(srcdir)/vecir.h \ - $(host_xm_file_list) \ + $(host_xm_file_list) target-gtypes.h \ $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \ $(srcdir)/alias.h $(srcdir)/coverage.c $(srcdir)/rtl.h \ $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(SYMTAB_H) \ @@ -3848,6 +3853,17 @@ build/genpreds.o : genpreds.c $(RTL_BASE build/genrecog.o : genrecog.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ coretypes.h $(GTM_H) errors.h $(READ_MD_H) gensupport.h +target-gtypes.h: s-target-gtypes; @true +# using struct instead of union makes this gty-safe. +s-target-gtypes: Makefile + (echo 'typedef union GTY (())'; \ + echo ' {'; \ + echo ' CUMULATIVE_ARGS GTY ((tag ("TARGET_NUM"))) _ca;'; \ + echo ' } cumulative_args_u;'; \ + ) >> tmp-target-gtypes.h + $(SHELL) $(srcdir)/../move-if-change tmp-target-gtypes.h target-gtypes.h + $(STAMP) s-target-gtypes + # Compile the programs that generate insn-* from the machine description. # They are compiled with $(COMPILER_FOR_BUILD), and associated libraries, # since they need to run on this machine Index: gcc/config/alpha/alpha.c =================================================================== --- gcc/config/alpha/alpha.c (revision 161310) +++ gcc/config/alpha/alpha.c (working copy) @@ -185,9 +185,9 @@ static struct alpha_rtx_cost_data const /* Get the number of args of a function in one of two ways. */ #if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK -#define NUM_ARGS crtl->args.info.num_args +#define NUM_ARGS INCOMING_ARGS_INFO (crtl->args).num_args #else -#define NUM_ARGS crtl->args.info +#define NUM_ARGS INCOMING_ARGS_INFO (crtl->args) #endif #define REG_PV 27 Index: gcc/config/frv/frv.c =================================================================== --- gcc/config/frv/frv.c (revision 161310) +++ gcc/config/frv/frv.c (working copy) @@ -2251,7 +2251,8 @@ static void frv_expand_builtin_va_start (tree valist, rtx nextarg) { tree t; - int num = crtl->args.info - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS; + int num + = INCOMING_ARGS_INFO (crtl->args) - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS; nextarg = gen_rtx_PLUS (Pmode, virtual_incoming_args_rtx, GEN_INT (UNITS_PER_WORD * num)); @@ -2259,7 +2260,7 @@ frv_expand_builtin_va_start (tree valist if (TARGET_DEBUG_ARG) { fprintf (stderr, "va_start: args_info = %d, num = %d\n", - crtl->args.info, num); + INCOMING_ARGS_INFO (crtl->args), num); debug_rtx (nextarg); } Index: gcc/config/s390/s390.c =================================================================== --- gcc/config/s390/s390.c (revision 161310) +++ gcc/config/s390/s390.c (working copy) @@ -7113,9 +7113,9 @@ s390_register_info (int clobbered_regs[] { /* Varargs functions need to save gprs 2 to 6. */ if (cfun->va_list_gpr_size - && crtl->args.info.gprs < GP_ARG_NUM_REG) + && INCOMING_ARGS_INFO (crtl->args).gprs < GP_ARG_NUM_REG) { - int min_gpr = crtl->args.info.gprs; + int min_gpr = INCOMING_ARGS_INFO (crtl->args).gprs; int max_gpr = min_gpr + cfun->va_list_gpr_size; if (max_gpr > GP_ARG_NUM_REG) max_gpr = GP_ARG_NUM_REG; @@ -7137,9 +7137,9 @@ s390_register_info (int clobbered_regs[] /* Mark f0, f2 for 31 bit and f0-f4 for 64 bit to be saved. */ if (TARGET_HARD_FLOAT && cfun->va_list_fpr_size - && crtl->args.info.fprs < FP_ARG_NUM_REG) + && INCOMING_ARGS_INFO (crtl->args).fprs < FP_ARG_NUM_REG) { - int min_fpr = crtl->args.info.fprs; + int min_fpr = INCOMING_ARGS_INFO (crtl->args).fprs; int max_fpr = min_fpr + cfun->va_list_fpr_size; if (max_fpr > FP_ARG_NUM_REG) max_fpr = FP_ARG_NUM_REG; @@ -8604,7 +8604,7 @@ s390_build_builtin_va_list (void) The following global variables are used to initialize the va_list structure: - crtl->args.info: + INCOMING_ARGS_INFO (crtl->args): holds number of gprs and fprs used for named arguments. crtl->args.arg_offset_rtx: holds the offset of the first anonymous stack argument @@ -8631,8 +8631,8 @@ s390_va_start (tree valist, rtx nextarg /* Count number of gp and fp argument registers used. */ - n_gpr = crtl->args.info.gprs; - n_fpr = crtl->args.info.fprs; + n_gpr = INCOMING_ARGS_INFO (crtl->args).gprs; + n_fpr = INCOMING_ARGS_INFO (crtl->args).fprs; if (cfun->va_list_gpr_size) { Index: gcc/config/spu/spu.c =================================================================== --- gcc/config/spu/spu.c (revision 161310) +++ gcc/config/spu/spu.c (working copy) @@ -4100,7 +4100,7 @@ spu_build_builtin_va_list (void) The following global variables are used to initialize the va_list structure: - crtl->args.info; + INCOMING_ARGS_INFO (crtl->args); the CUMULATIVE_ARGS for this function crtl->args.arg_offset_rtx: Index: gcc/config/sparc/sparc.c =================================================================== --- gcc/config/sparc/sparc.c (revision 161310) +++ gcc/config/sparc/sparc.c (working copy) @@ -5890,7 +5890,7 @@ sparc_function_value_regno_p (const unsi static rtx sparc_builtin_saveregs (void) { - int first_reg = crtl->args.info.words; + int first_reg = INCOMING_ARGS_INFO (crtl->args).words; rtx address; int regno; Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 161310) +++ gcc/config/i386/i386.c (working copy) @@ -7058,9 +7058,9 @@ ix86_va_start (tree valist, rtx nextarg) sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE); /* Count number of gp and fp argument registers used. */ - words = crtl->args.info.words; - n_gpr = crtl->args.info.regno; - n_fpr = crtl->args.info.sse_regno; + words = INCOMING_ARGS_INFO (crtl->args).words; + n_gpr = INCOMING_ARGS_INFO (crtl->args).regno; + n_fpr = INCOMING_ARGS_INFO (crtl->args).sse_regno; if (cfun->va_list_gpr_size) { Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 161310) +++ gcc/config/sh/sh.c (working copy) @@ -6519,7 +6519,7 @@ calc_live_regs (HARD_REG_SET *live_regs_ /* Force PR to be live if the prologue has to call the SHmedia argument decoder or register saver. */ if (TARGET_SHCOMPACT - && ((crtl->args.info.call_cookie + && ((INCOMING_ARGS_INFO (crtl->args).call_cookie & ~ CALL_COOKIE_RET_TRAMP (1)) || crtl->saves_all_registers)) pr_live = 1; @@ -6546,7 +6546,7 @@ calc_live_regs (HARD_REG_SET *live_regs_ : (/* Only push those regs which are used and need to be saved. */ (TARGET_SHCOMPACT && flag_pic - && crtl->args.info.call_cookie + && INCOMING_ARGS_INFO (crtl->args).call_cookie && reg == PIC_OFFSET_TABLE_REGNUM) || (df_regs_ever_live_p (reg) && ((!call_really_used_regs[reg] @@ -6802,14 +6802,15 @@ sh_expand_prologue (void) pretend_args = crtl->args.pretend_args_size; if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl) && (NPARM_REGS(SImode) - > crtl->args.info.arg_count[(int) SH_ARG_INT])) + > INCOMING_ARGS_INFO (crtl->args).arg_count[(int) SH_ARG_INT])) pretend_args = 0; /* Dwarf2 module doesn't expect frame related insns here. */ output_stack_adjust (-pretend_args - - crtl->args.info.stack_regs * 8, + - INCOMING_ARGS_INFO (crtl->args).stack_regs * 8, stack_pointer_rtx, 0, NULL, false); - if (TARGET_SHCOMPACT && flag_pic && crtl->args.info.call_cookie) + if (TARGET_SHCOMPACT && flag_pic + && INCOMING_ARGS_INFO (crtl->args).call_cookie) /* We're going to use the PIC register to load the address of the incoming-argument decoder and/or of the return trampoline from the GOT, so make sure the PIC register is preserved and @@ -6817,7 +6818,8 @@ sh_expand_prologue (void) df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true); if (TARGET_SHCOMPACT - && (crtl->args.info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1))) + && (INCOMING_ARGS_INFO (crtl->args).call_cookie + & ~ CALL_COOKIE_RET_TRAMP(1))) { int reg; @@ -6825,20 +6827,21 @@ sh_expand_prologue (void) be pushed onto the stack live, so that register renaming doesn't overwrite them. */ for (reg = 0; reg < NPARM_REGS (SImode); reg++) - if (CALL_COOKIE_STACKSEQ_GET (crtl->args.info.call_cookie) + if ((CALL_COOKIE_STACKSEQ_GET + (INCOMING_ARGS_INFO (crtl->args).call_cookie)) >= NPARM_REGS (SImode) - reg) for (; reg < NPARM_REGS (SImode); reg++) emit_insn (gen_shcompact_preserve_incoming_args (gen_rtx_REG (SImode, FIRST_PARM_REG + reg))); else if (CALL_COOKIE_INT_REG_GET - (crtl->args.info.call_cookie, reg) == 1) + (INCOMING_ARGS_INFO (crtl->args).call_cookie, reg) == 1) emit_insn (gen_shcompact_preserve_incoming_args (gen_rtx_REG (SImode, FIRST_PARM_REG + reg))); emit_move_insn (gen_rtx_REG (Pmode, MACL_REG), stack_pointer_rtx); emit_move_insn (gen_rtx_REG (SImode, R0_REG), - GEN_INT (crtl->args.info.call_cookie)); + GEN_INT (INCOMING_ARGS_INFO (crtl->args).call_cookie)); emit_move_insn (gen_rtx_REG (SImode, MACH_REG), gen_rtx_REG (SImode, R0_REG)); } @@ -6863,7 +6866,8 @@ sh_expand_prologue (void) rtx insn; if (i >= (NPARM_REGS(SImode) - - crtl->args.info.arg_count[(int) SH_ARG_INT] + - (INCOMING_ARGS_INFO + (crtl->args).arg_count[(int) SH_ARG_INT]) )) break; insn = push (rn); @@ -7119,7 +7123,8 @@ sh_expand_prologue (void) frame_insn (GEN_MOV (hard_frame_pointer_rtx, stack_pointer_rtx)); if (TARGET_SHCOMPACT - && (crtl->args.info.call_cookie & ~ CALL_COOKIE_RET_TRAMP(1))) + && (INCOMING_ARGS_INFO (crtl->args).call_cookie + & ~ CALL_COOKIE_RET_TRAMP(1))) { /* This must NOT go through the PLT, otherwise mach and macl may be clobbered. */ @@ -7381,7 +7386,7 @@ sh_expand_epilogue (bool sibcall_p) output_stack_adjust (crtl->args.pretend_args_size + save_size + d_rounding - + crtl->args.info.stack_regs * 8, + + INCOMING_ARGS_INFO (crtl->args).stack_regs * 8, stack_pointer_rtx, e, NULL, false); if (crtl->calls_eh_return) @@ -7504,11 +7509,13 @@ static rtx sh_builtin_saveregs (void) { /* First unnamed integer register. */ - int first_intreg = crtl->args.info.arg_count[(int) SH_ARG_INT]; + int first_intreg + = INCOMING_ARGS_INFO (crtl->args).arg_count[(int) SH_ARG_INT]; /* Number of integer registers we need to save. */ int n_intregs = MAX (0, NPARM_REGS (SImode) - first_intreg); /* First unnamed SFmode float reg */ - int first_floatreg = crtl->args.info.arg_count[(int) SH_ARG_FLOAT]; + int first_floatreg + = INCOMING_ARGS_INFO (crtl->args).arg_count[(int) SH_ARG_FLOAT]; /* Number of SFmode float regs to save. */ int n_floatregs = MAX (0, NPARM_REGS (SFmode) - first_floatreg); rtx regbuf, fpregs; @@ -7523,22 +7530,22 @@ sh_builtin_saveregs (void) while (pushregs < NPARM_REGS (SImode) - 1 && (CALL_COOKIE_INT_REG_GET - (crtl->args.info.call_cookie, + (INCOMING_ARGS_INFO (crtl->args).call_cookie, NPARM_REGS (SImode) - pushregs) == 1)) { - crtl->args.info.call_cookie + INCOMING_ARGS_INFO (crtl->args).call_cookie &= ~ CALL_COOKIE_INT_REG (NPARM_REGS (SImode) - pushregs, 1); pushregs++; } if (pushregs == NPARM_REGS (SImode)) - crtl->args.info.call_cookie + INCOMING_ARGS_INFO (crtl->args).call_cookie |= (CALL_COOKIE_INT_REG (0, 1) | CALL_COOKIE_STACKSEQ (pushregs - 1)); else - crtl->args.info.call_cookie + INCOMING_ARGS_INFO (crtl->args).call_cookie |= CALL_COOKIE_STACKSEQ (pushregs); crtl->args.pretend_args_size += 8 * n_intregs; @@ -7748,7 +7755,7 @@ sh_va_start (tree valist, rtx nextarg) TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - nfp = crtl->args.info.arg_count[SH_ARG_FLOAT]; + nfp = INCOMING_ARGS_INFO (crtl->args).arg_count[SH_ARG_FLOAT]; if (nfp < 8) nfp = 8 - nfp; else @@ -7763,7 +7770,7 @@ sh_va_start (tree valist, rtx nextarg) TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - nint = crtl->args.info.arg_count[SH_ARG_INT]; + nint = INCOMING_ARGS_INFO (crtl->args).arg_count[SH_ARG_INT]; if (nint < 4) nint = 4 - nint; else @@ -8550,11 +8557,11 @@ initial_elimination_offset (int from, in if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM) return total_saved_regs_space + total_auto_space - + crtl->args.info.byref_regs * 8; + + INCOMING_ARGS_INFO (crtl->args).byref_regs * 8; if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) return total_saved_regs_space + total_auto_space - + crtl->args.info.byref_regs * 8; + + INCOMING_ARGS_INFO (crtl->args).byref_regs * 8; /* Initial gap between fp and sp is 0. */ if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM) @@ -10126,7 +10133,7 @@ sh_allocate_initial_value (rtx hard_reg) if (current_function_is_leaf && ! sh_pr_n_sets () && ! (TARGET_SHCOMPACT - && ((crtl->args.info.call_cookie + && ((INCOMING_ARGS_INFO (crtl->args).call_cookie & ~ CALL_COOKIE_RET_TRAMP (1)) || crtl->saves_all_registers))) x = hard_reg; @@ -10736,7 +10743,7 @@ sh_function_ok_for_sibcall (tree decl, t { return (1 && (! TARGET_SHCOMPACT - || crtl->args.info.stack_regs == 0) + || INCOMING_ARGS_INFO (crtl->args).stack_regs == 0) && ! sh_cfun_interrupt_handler_p () && (! flag_pic || (decl && ! TREE_PUBLIC (decl)) @@ -11651,7 +11658,7 @@ sh_get_pr_initial_val (void) PR register on SHcompact, because it might be clobbered by the prologue. We check first if that is known to be the case. */ if (TARGET_SHCOMPACT - && ((crtl->args.info.call_cookie + && ((INCOMING_ARGS_INFO (crtl->args).call_cookie & ~ CALL_COOKIE_RET_TRAMP (1)) || crtl->saves_all_registers)) return gen_frame_mem (SImode, return_address_pointer_rtx); Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 161310) +++ gcc/config/sh/sh.md (working copy) @@ -9018,7 +9018,8 @@ (define_expand "return" } if (TARGET_SHCOMPACT - && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))) + && (INCOMING_ARGS_INFO (crtl->args).call_cookie + & CALL_COOKIE_RET_TRAMP (1))) { emit_jump_insn (gen_shcompact_return_tramp ()); DONE; @@ -9028,7 +9029,7 @@ (define_expand "return" (define_insn "*return_i" [(return)] "TARGET_SH1 && ! (TARGET_SHCOMPACT - && (crtl->args.info.call_cookie + && (INCOMING_ARGS_INFO (crtl->args).call_cookie & CALL_COOKIE_RET_TRAMP (1))) && reload_completed && lookup_attribute (\"trap_exit\", @@ -9055,7 +9056,7 @@ (define_insn "*return_trapa" (define_expand "shcompact_return_tramp" [(return)] "TARGET_SHCOMPACT - && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))" + && (INCOMING_ARGS_INFO (crtl->args).call_cookie & CALL_COOKIE_RET_TRAMP (1))" " { rtx reg = gen_rtx_REG (Pmode, R0_REG); @@ -9068,7 +9069,7 @@ (define_expand "shcompact_return_tramp" (define_insn "shcompact_return_tramp_i" [(parallel [(return) (use (reg:SI R0_REG))])] "TARGET_SHCOMPACT - && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))" + && (INCOMING_ARGS_INFO (crtl->args).call_cookie & CALL_COOKIE_RET_TRAMP (1))" "jmp @r0%#" [(set_attr "type" "jump_ind") (set_attr "needs_delay_slot" "yes")]) Index: gcc/config/avr/avr.c =================================================================== --- gcc/config/avr/avr.c (revision 161310) +++ gcc/config/avr/avr.c (working copy) @@ -2748,7 +2748,7 @@ bool avr_frame_pointer_required_p (void) { return (cfun->calls_alloca - || crtl->args.info.nregs == 0 + || INCOMING_ARGS_INFO (crtl->args).nregs == 0 || get_frame_size () > 0); } Index: gcc/config/xtensa/xtensa.c =================================================================== --- gcc/config/xtensa/xtensa.c (revision 161310) +++ gcc/config/xtensa/xtensa.c (working copy) @@ -2699,7 +2699,7 @@ static rtx xtensa_builtin_saveregs (void) { rtx gp_regs; - int arg_words = crtl->args.info.arg_words; + int arg_words = INCOMING_ARGS_INFO (crtl->args).arg_words; int gp_left = MAX_ARGS_IN_REGISTERS - arg_words; if (gp_left <= 0) @@ -2736,7 +2736,7 @@ xtensa_va_start (tree valist, rtx nextar tree t, u; int arg_words; - arg_words = crtl->args.info.arg_words; + arg_words = INCOMING_ARGS_INFO (crtl->args).arg_words; f_stk = TYPE_FIELDS (va_list_type_node); f_reg = TREE_CHAIN (f_stk); @@ -3131,7 +3131,7 @@ order_regs_for_local_alloc (void) /* Use the AR registers in increasing order (skipping a0 and a1) but save the incoming argument registers for a last resort. */ - num_arg_regs = crtl->args.info.arg_words; + num_arg_regs = INCOMING_ARGS_INFO (crtl->args).arg_words; if (num_arg_regs > MAX_ARGS_IN_REGISTERS) num_arg_regs = MAX_ARGS_IN_REGISTERS; for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++) Index: gcc/config/stormy16/stormy16.c =================================================================== --- gcc/config/stormy16/stormy16.c (revision 161310) +++ gcc/config/stormy16/stormy16.c (working copy) @@ -1355,7 +1355,7 @@ xstormy16_expand_builtin_va_start (tree t = build2 (MODIFY_EXPR, TREE_TYPE (count), count, build_int_cst (NULL_TREE, - crtl->args.info * UNITS_PER_WORD)); + INCOMING_ARGS_INFO (crtl->args) * UNITS_PER_WORD)); TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); } Index: gcc/config/m68hc11/m68hc11.c =================================================================== --- gcc/config/m68hc11/m68hc11.c (revision 161310) +++ gcc/config/m68hc11/m68hc11.c (working copy) @@ -1617,7 +1617,7 @@ expand_prologue (void) If the first argument is a 32-bit quantity, the D+X registers are used. Use Y to compute the frame. Otherwise, X is cheaper. For 68HC12, this scratch register is not used. */ - if (crtl->args.info.nregs == 2) + if (INCOMING_ARGS_INFO (crtl->args).nregs == 2) scratch = iy_reg; else scratch = ix_reg; Index: gcc/config/iq2000/iq2000.c =================================================================== --- gcc/config/iq2000/iq2000.c (revision 161310) +++ gcc/config/iq2000/iq2000.c (working copy) @@ -1376,7 +1376,7 @@ iq2000_va_start (tree valist, rtx nextar /* Find out how many non-float named formals. */ int gpr_save_area_size; /* Note UNITS_PER_WORD is 4 bytes. */ - int_arg_words = crtl->args.info.arg_words; + int_arg_words = INCOMING_ARGS_INFO (crtl->args).arg_words; if (int_arg_words < 8 ) /* Adjust for the prologue's economy measure. */ Index: gcc/config/ia64/ia64.c =================================================================== --- gcc/config/ia64/ia64.c (revision 161310) +++ gcc/config/ia64/ia64.c (working copy) @@ -3152,7 +3152,8 @@ ia64_expand_prologue (void) /* We don't need an alloc instruction if we've used no outputs or locals. */ if (current_frame_info.n_local_regs == 0 && current_frame_info.n_output_regs == 0 - && current_frame_info.n_input_regs <= crtl->args.info.int_regs + && (current_frame_info.n_input_regs + <= INCOMING_ARGS_INFO (crtl->args).int_regs) && !TEST_HARD_REG_BIT (current_frame_info.mask, AR_PFS_REGNUM)) { /* If there is no alloc, but there are input registers used, then we Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 161310) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -8718,10 +8718,10 @@ rs6000_va_start (tree valist, rtx nextar f_sav, NULL_TREE); /* Count number of gp and fp argument registers used. */ - words = crtl->args.info.words; - n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG, + words = INCOMING_ARGS_INFO (crtl->args).words; + n_gpr = MIN (INCOMING_ARGS_INFO (crtl->args).sysv_gregno - GP_ARG_MIN_REG, GP_ARG_NUM_REG); - n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG, + n_fpr = MIN (INCOMING_ARGS_INFO (crtl->args).fregno - FP_ARG_MIN_REG, FP_ARG_NUM_REG); if (TARGET_DEBUG_ARG) @@ -17399,7 +17399,8 @@ compute_vrsave_mask (void) them in again. More importantly, the mask we compute here is used to generate CLOBBERs in the set_vrsave insn, and we do not wish the argument registers to die. */ - for (i = crtl->args.info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i) + for (i = INCOMING_ARGS_INFO (crtl->args).vregno - 1; + i >= ALTIVEC_ARG_MIN_REG; --i) mask &= ~ALTIVEC_REG_BIT (i); /* Similarly, remove the return value from the set. */ Index: gcc/config/arc/arc.c =================================================================== --- gcc/config/arc/arc.c (revision 161310) +++ gcc/config/arc/arc.c (working copy) @@ -2277,8 +2277,8 @@ static void arc_va_start (tree valist, rtx nextarg) { /* See arc_setup_incoming_varargs for reasons for this oddity. */ - if (crtl->args.info < 8 - && (crtl->args.info & 1)) + if (INCOMING_ARGS_INFO (crtl->args) < 8 + && (INCOMING_ARGS_INFO (crtl->args) & 1)) nextarg = plus_constant (nextarg, UNITS_PER_WORD); std_expand_builtin_va_start (valist, nextarg); Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 161310) +++ gcc/config/arm/arm.c (working copy) @@ -5059,7 +5059,7 @@ thumb_find_work_register (unsigned long if (! cfun->machine->uses_anonymous_args && crtl->args.size >= 0 && crtl->args.size <= (LAST_ARG_REGNUM * UNITS_PER_WORD) - && crtl->args.info.nregs < 4) + && INCOMING_ARGS_INFO (crtl->args).nregs < 4) return LAST_ARG_REGNUM; /* Otherwise look for a call-saved register that is going to be pushed. */ Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (revision 161310) +++ gcc/config/mips/mips.c (working copy) @@ -5472,7 +5472,7 @@ mips_va_start (tree valist, rtx nextarg) int fpr_save_area_size; int fpr_offset; - cum = &crtl->args.info; + cum = &INCOMING_ARGS_INFO (crtl->args); gpr_save_area_size = (MAX_ARGS_IN_REGISTERS - cum->num_gprs) * UNITS_PER_WORD; fpr_save_area_size @@ -6015,7 +6015,8 @@ mips16_build_function_stub (void) fprintf (asm_out_file, "\t# Stub function for %s (", current_function_name ()); separator = ""; - for (f = (unsigned int) crtl->args.info.fp_code; f != 0; f >>= 2) + for (f = (unsigned int) INCOMING_ARGS_INFO (crtl->args).fp_code; + f != 0; f >>= 2) { fprintf (asm_out_file, "%s%s", separator, (f & 3) == 1 ? "float" : "double"); @@ -6051,7 +6052,7 @@ mips16_build_function_stub (void) output_asm_insn ("la\t%^,%0", &symbol); /* Move the arguments from floating-point registers to general registers. */ - mips_output_args_xfer (crtl->args.info.fp_code, 'f'); + mips_output_args_xfer (INCOMING_ARGS_INFO (crtl->args).fp_code, 'f'); /* Jump to the MIPS16 function. */ output_asm_insn ("jr\t%^", NULL); @@ -9814,7 +9815,7 @@ mips_output_function_prologue (FILE *fil floating-point arguments. */ if (TARGET_MIPS16 && TARGET_HARD_FLOAT_ABI - && crtl->args.info.fp_code != 0) + && INCOMING_ARGS_INFO (crtl->args).fp_code != 0) mips16_build_function_stub (); /* Get the function name the same way that toplev.c does before calling Index: gcc/config/v850/v850.c =================================================================== --- gcc/config/v850/v850.c (revision 161310) +++ gcc/config/v850/v850.c (working copy) @@ -1583,7 +1583,7 @@ expand_prologue (void) } /* Save arg registers to the stack if necessary. */ - else if (crtl->args.info.anonymous_args) + else if (INCOMING_ARGS_INFO (crtl->args).anonymous_args) { if (TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT) emit_insn (gen_save_r6_r9_v850e ()); Index: gcc/config/mmix/mmix.c =================================================================== --- gcc/config/mmix/mmix.c (revision 161310) +++ gcc/config/mmix/mmix.c (working copy) @@ -831,9 +831,9 @@ mmix_reorg (void) wasteful to optimize for unused parameter registers. As of 2002-04-30, df_regs_ever_live_p (n) seems to be set for only-reads too, but that might change. */ - if (!TARGET_ABI_GNU && regno < crtl->args.info.regs - 1) + if (!TARGET_ABI_GNU && regno < INCOMING_ARGS_INFO (crtl->args).regs - 1) { - regno = crtl->args.info.regs - 1; + regno = INCOMING_ARGS_INFO (crtl->args).regs - 1; /* We don't want to let this cause us to go over the limit and make incoming parameter registers be misnumbered and treating the last