This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

Attachment: split_logic_and_extesnions.patch.gz
Description: GNU Zip compressed data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]