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] |
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] |