Steven Bosscher wrote on Sonntag, 7. August 2005 12:45 : > On Sunday 07 August 2005 09:35, Björn Haase wrote: > > Hello, > > > > The avr port presently misses possible intra-procedure optimizations > > concerning register use. > > What you describe is an _inter_procedural optimization. "Between > procedures". You want to use the result of some analysis done in one > function to expose extra optimization opportunities in another function. > That is interprocedural. OK, thank's :-).
> > Is there a way to make leaf functions to be compiled first > > Leaf functions _are_ compiled first. > > > so that when > > starting with non-leaf functions in the same unit expand could insert > > detailed information on which subset of registers is actually clobbered > > by calls to leaf functions? > > Not at the moment. It is probably not very hard to implement something > like this idea, though. Note that you can even propagate this detailed > information across the call graph if you could compute it. I think that such kind of optimization could help very much for my fractional numerics library where some functions tend to be lengthy but use very few registers. I would be willing to try to implement it. I can imagine two possible approaches for addressing the issue. One that only needs adaptions in the back-end and implements the optimization only for one target and then one more generic solution. 1.) target specific approach The back end implements a database that stores the register usage of all the functions that so far have been compiled and the symbol ref of these functions. IIUC this could be done in the final stage when generating the asm text output. The define_insn for the named call pattern is replaced by a smart define_expand that looks in the database whether anything on the function-to-be-called is known. It could look whether the database already contains an entry with the same label ref. If not, it generates the usual call pattern. If there *is* an entry in the database it generates a call_insn where the CALL_INSN_FUNCTION_USAGE contains the appropriate use and clobber RTL. 2.) generic One could of course try to store the information on register usage somewhere in the tree structure. One therefore would add a target macro CALL_FUNCTION_CLOBBERED_REGISTERS that returns a pointer to static memory of a struct of the same type as the "CALL_REALLY_USED_REGISTERS" struct with the only difference that this struct could change. If the value returned is not NULL, the mid end then would copy this struct to a new location on the heap and store a link to this storage somewhere in the tree data structure. One would then make the default expander for calls do the work to adapt the CALL_INSN_FUNCTION_USAGE field if information is available. Probably one would then not make use the name of the lable ref of the function entry lable. The default expander probably would have a pointer to some tree node that describes the function to be called.? I think that I am having a clear idea on how much work it would be to implement 1). IMO, it would not be too much work (only open question would be, where to place the code that finds out which register are used). However, I'd prefer method 2) since I think that other targets might as well benefit from the optimization. I only cannot judge how much work it would be to get the additional information stored within the tree. I'd appreciate opinions on whether there stand chances to get approach 2) integrated into gcc mainline. I also would be thankful for a short hint where the function is that would have to use the suggested CALL_FUNCTION_CLOBBERED_REGISTERS macro and where within the mid-end I would find the default expander for insn calls (I thought it is in optabs.c but I did not find it immediately). Greetings, Bjoern Haase