% cp ~cs253/Examples/Inline/* . % head *.h *.cc ==> Numbers.h <== class Numbers { public: static int two(), three(); }; ==> main.cc <== #include "Numbers.h" int main() { return Numbers::two() + Numbers::three(); } ==> Numbers.cc <== #include "Numbers.h" int Numbers::two() { return 2; } int Numbers::three() { return 3; }
% cp ~cs253/Examples/Inline/* . % g++ -Wall -c main.cc % g++ -Wall -c Numbers.cc % g++ -Wall main.o Numbers.o % objdump --no-show-raw-insn -Cd | sed -n '/<main>/,/^$/p' 0000000000400556 <main>: 400556: push %rbp 400557: mov %rsp,%rbp 40055a: push %rbx 40055b: sub $0x8,%rsp 40055f: callq 400574 <Numbers::two()> 400564: mov %eax,%ebx 400566: callq 400580 <Numbers::three()> 40056b: add %ebx,%eax 40056d: add $0x8,%rsp 400571: pop %rbx 400572: pop %rbp 400573: retq
main()
called Numbers::two()
. This is not surprising.
There are several optimization arguments to g++
:
-O
— general optimization
-O1
— same as -O
-O2
— more optimization
-O3
— tons of optimization
% cp ~cs253/Examples/Inline/* . % g++ -Wall -O3 -c main.cc % g++ -Wall -O3 -c Numbers.cc % g++ -Wall -O3 main.o Numbers.o % objdump --no-show-raw-insn -Cd | sed -n '/<main>/,/^$/p' 0000000000400470 <main>: 400470: push %rbx 400471: callq 400580 <Numbers::two()> 400476: mov %eax,%ebx 400478: callq 400590 <Numbers::three()> 40047d: add %ebx,%eax 40047f: pop %rbx 400480: retq
Fewer instructions—good. Still called Numbers::two()
,
which really can’t be avoided.
-flto
— Perform link-time optimization
This tells the linker to perform optimization between
the individual *.o
object files.
% cp ~cs253/Examples/Inline/* . % g++ -Wall -O3 -flto -c main.cc % g++ -Wall -O3 -flto -c Numbers.cc % g++ -Wall -O3 -flto main.o Numbers.o % objdump --no-show-raw-insn -Cd | sed -n '/<main>/,/^$/p' 0000000000400470 <main>: 400470: mov $0x5,%eax 400475: retq
Holy smokes! 😲
g++ -O3 -flto
.