http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52543
Bug #: 52543 Summary: lower-subreg.c: code bloat of 300%-400% for bulti-word memory splits Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: g...@gcc.gnu.org Target: avr lower-subreg.c causes extreme code bloat for some memory accesses because it does not take into account the additional costs caused by the split. Example code for AVR address spaces: long readx (const __memx long *p) { return *p; } long read1 (const __flash1 long *p) { return *p; } long read0 (const __flash long *p) { return *p; } Reason is that read from these address spaces need one preparation sequence (set up segment register) per read. Thus: For one 4-byte read there will be one preparation sequence. For 4 one-byte reads there will be 4 preparation sequences. For the __flash address space no preparation is needed, but a 32-bit read can use post-increment addressing whereas a split to 4 byte moves won't use post-increment because GCC is completely afraid of pre-/post-modify addressing. The only place to hook in could be mode_dependent_address, however, that hook just passes the address down to the backend but omits the address space in use. As all 16-bit address spaces (including generic) use HImode as pointer mode, the target cannot take a decision based on the address alone. Configured with: ../../gcc.gnu.org/trunk/configure --target=avr --prefix=/local/gnu/install/gcc-4.7 --disable-nls --with-dwarf2 --enable-checking=yes,rtl --enable-languages=c,c++ gcc version 4.8.0 20120307 (experimental) (GCC)