1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
extern int one ;
struct A
{
virtual ~A() ;
virtual void foo() { ++one ; }
void bar() { ++one ; }
};
int call_virtually( A* pa )
{
one = 78 ;
int two = one + 56 ;
pa->foo() ;
++one ;
--two ;
pa->foo() ;
--one ;
two += 10 ;
if( two > one )
{
return two - one ;
}
else
{
return one - two ;
}
/*
> g++ -std=c++11 -Wall -pedantic-errors -fomit-frame-pointer -O3 -c -S test.cc
__Z14call_virtuallyP1A:
pushl %ebx
subl $8, %esp
movl 16(%esp), %ebx
movl $78, _one
movl (%ebx), %eax
movl %ebx, %ecx
call *8(%eax)
movl (%ebx), %eax
movl %ebx, %ecx
addl $1, _one
call *8(%eax)
movl _one, %edx
leal -1(%edx), %ecx
cmpl $142, %ecx
movl %ecx, _one
leal -144(%edx), %eax
jg L3
movl $144, %eax
subl %edx, %eax
L3:
addl $8, %esp
popl %ebx
ret
*/
}
int call_non_virtually( A* pa )
{
one = 78 ; // constant folding: one == 78
int two = one + 56 ; // // constant folding: two == 134
pa->bar() ; // inlined, constant folding: one == 79
++one ; // constant folding: one == 80
--two ; // constant folding: two == 133
pa->bar() ; // inlined, constant folding: one == 81
--one ; // constant folding: one == 80
two += 10 ; // constant folding: two == 123
if( two > one ) // constant folding: true, dead code elimination
{
// def-use: assign 80 to one
return two - one ; // constant folding: return 63 ;
}
else
{
return one - two ; // dead code elimination
}
/*
> g++ -std=c++11 -Wall -pedantic-errors -fomit-frame-pointer -O3 -c -S test.cc
__Z18call_non_virtuallyP1A:
movl $80, _one
movl $63, %eax
ret
*/
}
|