[PATCH] AVR: implement HI/SI logic operations and sign/zero extension by define_insn_and_split instead of define_insn

Björn Haase bjoern.m.haase@web.de
Sun Apr 3 20:50:00 GMT 2005


Hi,

here is the first result of my work on the "splitting" issue for AVR.
Find enclosed a patch that passed my testsuite run without any regression.

I have been experimenting for quite a while with doing the spliting at
expand time and after reload.

In theory, I came to the conclusion that it would be best, to
expose the complexity as soon as possible to the compiler. I.e. do the
splitting as soon as possible. Mainly in order to give the register allocator
all the knowledge on which register is actually needed. However, I now think
that Denis initial suggestion is best for most patterns: "Do it after 
reload :-)". 
In my opinion, the main problem is that when doing the splitting 
at *expand* is twofold:

1.) It will probably be 
almost impossible to recycle the condition codes that are readily generated
by the calculating instructions (i.e. sub, add) so that one can prevent
spurious cp/cpc instructions. In the case of sign tests, I do not think 
that this is a severe problem since we have efficient patterns for that
without needing lots of compares. But all of the instructions that leave
useful information beside the sign, I'd suggest to split them after reload.
Also the optimizer will have difficulties to optimize branching conditions
if one expands the patterns for and and or at RTL generation. E.g. it would
probably be extremely difficult to re-implement the branching patterns for 
the single bit tests and the sign test. In order to make combine use
the more efficient combined patterns of type "sign_extend_value_and_substract"
one also would need to leave zero_extend and sign_extend intact until after
reload.

2.) Second difficulty are moves.
When using subreg expressions for expanding moves, one will have 
difficulties to tell the
compiler that a [(set reg:SI 24) (set reg:SI 22)] is indeed possible without
an intermediate non-overlapping register array. Also, it would be hard to
make the compiler use the "movw" instructions in case that one has atomized
everything to QImode objects. I think that one should split moves only after
expand for this reason.

However, for the remaining patterns (e.g. shifts, multiplies, xor) that do not
leave the condition code in a useful state it is my feeling that it would
be best to try to expand them as early as possible. 
Maybe this way, one might also prevent unnecessary clearing of the zero 
register and
maybe for the case of multiplication, one might need less registers if the 
product is
only an intermediate result or if the target for the product is memory.
On the other hand, one would probably need to add quite a number of "use 
zero_reg" 
and (clobber temp_reg) information in the instruction patterns.

My tests have shown that when using the splitters, code gets considerably 
better for complex logic operations. For my real-world application of 16k, I 
have observed about 50 bytes smaller code.

Yours,

Björn


2005-03-04  Bjoern Haase <bjoern.m.haase@web.de>

	* config/avr/avr.md:
	replace magic numbers for unspec numbering by (define_constants ). 
	add new unspec for generation of sign extension byte.
	extend define_insn to define_insn_and_split for the patterns...
	"andhi" (here also tiny change in define_insn pattern), "andsi"
	"iorhi", "iorhi_clobber", "iorsi", "iorsi_clobber"
	"extendqihi2", "extendqisi2", "extendhisi2" 
	"zero_extendqihi2", "zero_extendqisi2", "zero_extendhisi2"
	replace "xorhi" and "xorsi" patterns by expanders
-------------- next part --------------
A non-text attachment was scrubbed...
Name: split_logic_and_extesnions.patch.gz
Type: application/x-gzip
Size: 3176 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20050403/02d06d7d/attachment.bin>


More information about the Gcc-patches mailing list