Out of hacker curiosity, I wonder how gcc
can manage to optimize the function below this smartly?
int c() {
int i, j = 0;
for (i = 0; i < 10; i++) {
j += i;
}
return j;
}
$objdump -D c.o
below is for arm but x86 is no different in logic.
00000000 <c>:
0: 202d movs r0, #45 ; 0x2d
2: 4770 bx lr
I mostly wonder if this is result of a chain of optimizations or something like a template match? Are there any documentation on such optimizations?
The compiler optimizes to reduce the size of the binary instead of execution speed. If you do not specify an optimization option, gcc attempts to reduce the compilation time and to make debugging always yield the result expected from reading the source code.
In computing, an optimizing compiler is a compiler that tries to minimize or maximize some attributes of an executable computer program. Common requirements are to minimize a program's execution time, memory footprint, storage size, and power consumption (the last three being popular for portable computers).
GCC is an integrated distribution of compilers for several major programming languages. These languages currently include C, C++, Objective-C, Objective-C++, Java, Fortran, and Ada. Lets go through the compilation process of a simple C program and understand whats happening behind the scenes.
Known as the GNU C Compiler at the time, GCC has evolved to serve other languages such as Java and C++, and has changed its name to GNU Compiler Collection to reflect the multitude of languages it now supports. There are four steps in the GCC compilation process: preprocessor, compiler, assembler, and linker.
The optimizer does this in phases/passes... when you specify -O2 there are many optimizations that are enabled. The principal optimizations that come into play here are
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
so this code
int i, j = 0;
for (i = 0; i < 10; i++) {
j += i;
}
return j;
after loop unrolling becomes
int i, j = 0;
i=0; j += i;
i=1; j += i;
i=2; j += i;
i=3; j += i;
i=4; j += i;
i=5; j += i;
i=6; j += i;
i=7; j += i;
i=8; j += i;
i=9; j += i;
return j;
after constant propagation pass
int i, j = 0;
i=0; j += 0;
i=1; j += 1;
i=2; j += 2;
i=3; j += 3;
i=4; j += 4;
i=5; j += 5;
i=6; j += 6;
i=7; j += 7;
i=8; j += 8;
i=9; j += 9;
return j;
after dead-code elimination
j = 0;
j += 0;
j += 1;
j += 2;
j += 3;
j += 4;
j += 5;
j += 6;
j += 7;
j += 8;
j += 9;
return j;
after constant folding
j = 45;
return j;
and finally,
return 45;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With