Here is a simple program that has been profiled with using gprof.
We can see that if the program is compiled with option -O3
then gprof's output doesn't contained called functions foo1() and foo2().
Any explanation ?
========= C code : BEGIN =========
/* File main.c */
int foo1 (int argc) { return argc; }
int foo2 (int argc) { return argc; }
int main(int argc)
{
return (foo1(argc) + foo2(argc));
}
========= C code : END ===========
========= Compiling & Running : BEGIN =========
% gcc -o a0.exe main.c -g -pg
% a0.exe
% gprof -b a0.exe
Flat profile:
Each sample counts as 0.0555556 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 foo1
0.00 0.00 0.00 1 0.00 0.00 foo2
0.00 0.00 0.00 1 0.00 0.00 main
[---omitted---]
-----------------------------------------------
% gcc -O1 -o a1.exe main.c -g -pg
% a1.exe
% gprof -b a1.exe
Flat profile:
Each sample counts as 0.0555556 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 foo1
0.00 0.00 0.00 1 0.00 0.00 foo2
0.00 0.00 0.00 1 0.00 0.00 main
[---omitted---]
-----------------------------------------------
% gcc -O2 -o a2.exe main.c -g -pg
% a2.exe
% gprof -b a2.exe
Flat profile:
Each sample counts as 0.0555556 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 foo1
0.00 0.00 0.00 1 0.00 0.00 foo2
0.00 0.00 0.00 1 0.00 0.00 main
[---omitted---]
-----------------------------------------------
% gcc -O3 -o a3.exe main.c -g -pg
% a3.exe
% gprof -b a3.exe
Flat profile:
Each sample counts as 0.0555556 seconds.
no time accumulated
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 main
[---omitted---]
========= Compiling & Running : END ===========
=================================
Alex Vinokur
mailto:ale...@connect.to
http://www.simtel.net/pub/oth/19088.html
=================================
The optimisation -O3 inlines simple functions (like yours here). There are
no calls to trace.
HTH
Tauno Voipio
tauno voipio @ iki fi
How can we see that ?
For instance, nm doesn't distinguish -O0, -O1, -O2, -O3.
====================
Windows 2000
DJGPP 2.03
GNU gcc/g++ version 3.2.1
GNU nm 2.13
====================
gcc -o a0.exe main.c -g -pg
nm a0.exe | grep foo
000016d0 T _foo1
000016e2 T _foo2
gcc -O1 -o a1.exe main.c -g -pg
nm a1.exe | grep foo
000016d0 T _foo1
000016e2 T _foo2
gcc -O2 -o a2.exe main.c -g -pg
nm a2.exe | grep foo
000016d0 T _foo1
000016f0 T _foo2
gcc -O3 -o a3.exe main.c -g -pg
nm a3.exe | grep foo
000016f0 T _foo1
00001710 T _foo2
By looking at the produced assembler...
> For instance, nm doesn't distinguish -O0, -O1, -O2, -O3.
The function definitions have to be there in case you want to access them
from another translation unit.
Try to make the functions "static". As the the functions are no longer
accessible from the outside I'd expect the symbols to be removed
completely. But that's just a wild guess.
Andre'
--
Those who desire to give up Freedom in order to gain Security,
will not have, nor do they deserve, either one. (T. Jefferson)
Right.
Also, if the functions are not 'static', there will be one copy of each
generated function for accesses from outside of the module. The internal
calls may still be inlined with nothing to trace.
Because you did not declare the functions static, they were still included
as discrete functions in the output (so that other modules can access them).
However, the compiler has also inlined copies of those functions in main()
(since the functions were so simple).
Your code:
========= C code : BEGIN =========
/* File main.c */
int foo1 (int argc) { return argc; }
int foo2 (int argc) { return argc; }
int main(int argc)
{
return (foo1(argc) + foo2(argc));
}
========= C code : END ===========
is optimized by -O3 so that it appears to be:
========= C code : BEGIN =========
/* File main.c */
int foo1 (int argc) { return argc; }
int foo2 (int argc) { return argc; }
int main(int argc)
{
return ((argc) + (argc));