On ARM target when the compiler can deduce that the result of a calculation is
a constant, it always substitutes the calculation with the constant, even if
loading the constant is more expensive (both in code size and execution time)
than the actual calculation. 

I attach a file that contains two short C functions. They do exactly the same,
but foo() processes a constant while bar() processes its argument. Compiling
the code with -Os, -O2 or -O3 results in code where processing the argument is
much shorter and faster than processing the constant. 

In particular, processing the variable argument generates code (the same
assembly is generated for -Os and -O3) that is 7 words long and executes in 14
clocks. Using -Os, the function processing a constant generates a 10 word, 25
clock assembly while -O2 or -O3 creates a 17 words, 24 clock code.

That is, when a constant is given instead of a variable parameter, the
generated code is 40% longer and 79% slower for -Os and 143% longer and 71%
slower with -O3.

Adding the load of the constant to the beginning of the variable argument
version of the code would cost 1 word, 1 clock if the peephole optimiser was
clever enough and 2 words, 3 clocks in the worst case. Nowhere near the 3
words, 11 clocks (-Os) or 10 words, 10 clocks (-O2,-O3) cost the compiler
generated.


The command line used was:

arm-aebi-gcc-4.4.0 -S -O[s23] constant.c


-- 
           Summary: Calculated values replaced with constants even if he
                    constants cost more than the calculations
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: zoltan at bendor dot com dot au
  GCC host triplet: i386-elf-linux
GCC target triplet: arm-eabi-unknown


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39469

Reply via email to