This is the mail archive of the
mailing list for the GCC project.
Re: avr-back-end: instruction splitting issue
- From: Denis Chertykov <denisc at overta dot ru>
- To: "Bjіrn Haase" <Bjoern dot M dot Haase at web dot de>
- Cc: "DenisChertykov" <denisc at overta dot ru>, gcc at gcc dot gnu dot org
- Date: 08 Jan 2005 08:51:07 +0300
- Subject: Re: avr-back-end: instruction splitting issue
- References: <email@example.com>
"Björn Haase" <Bjoern.M.Haase@web.de> writes:
> Hi Denis,
> as you had suggested, I have been thinking a bit about the "instruction
> splitting issue", e.g. splitting a plus:SI to four QI operations of type
> "add / adc / adc / adc". You had suggested to do it analogous to the arm
> port machine description for its DI operations.
> I have been thinking about this solution and have so far been making some
> experiments. There are a couple of reasons why this approach does not satisfy me
> so far and I would like to discuss this. I namely think that doing the
> splitting with "define_insn_and_split" only after reload would be too late for my
> personal taste. In my opinion, if one considers reworking the back-and such that
> it uses instruction splitting, one should try hard to split to native instructions as
> early as possible:
> One main reason why I am convinced that splitting of the SI and HI instructions
> could result in much better code is that I have the hope that this way one
> could reduce the load on the register file. I.e. I hope that one could teach
> the compiler this way to use less registers.
> One sample case where the compiler generates code that I dislike is, e.g.,
> the following situation.
> Assume that you are having a function that has a local SI:register variable "a"
> and that uses a SI:memory reference "b".
> Assume further that you want to calculate a = a+b; and that this is the
> only time in the function that you ever use b.
> As an assembler programer, one would have the possibility to implement this
> without needing to copy b into a single additional register. One could readily
> load the individual bytes of b into __temp_register__ and add them step by
> step. The compiler presently loads "b" entirely in registers and, thus,
> wastes 4 of them.
> In my opinion the only way to improve such a situation would be to find
> some way to do the splitting before register allocation.
> In my opinion the best solution would be to do the splitting immediately
> after "expand", i.e. immediately after RTL generation. What I am thinking
> about is, to try to implement a scheme, where RTL instructions are generated
> and expanded as usual. I.e. the compiler would continue to generate operations
> like plus:SI or cmp:HI. I'd suggest to add then an additional "atomize" pass
> that gets rid of all references to HI and SI objects in the RTL that could
> be eliminated. The only objects that one could not replace would, in my opinion
> be memory references to SI and HI objects and those variables that happen
> to be in fixed registers already after "expand". (i.e. the function's
> parameters and return values and the parameter the function itself passes
> to other functions). After this "atomize" pass there would remain only
> instructions that actually correspond to real avr instructions.
> I have the hope that this way, one could realize an improvement of
> the code density. I however fear, that this way one might prevent the
> compiler to make some optimizations that could be done only when the
> SI and HI objects are considered to be monolithic objects.
> (I'm namely thinking about movw.)
> I'm avare of the fact that this would be a quite tedious task since about
> all these things that are presently covered in instruction patterns would
> be required in this atomize pass.
> What do You think about this issue?
I have suggested splitting after reload (or immediately before
register allocation) because GCC have a lot of optimization before
reload and many of this optimizations work better with SI, HI, mode
(not with subregs).
But, you can try and look to results. May be I'm wrong.