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)

Reply via email to