Consider the following code:
int fac_aux( int x, int res ) {
if( x == 1 ) return res;
else return fac_aux( x - 1, res * x );
}
int fac( int x ) {
return fac_aux( x, 1 );
}
int main() {
int x = fac( 50 );
std::cout << x;
return 0;
}
According to generated asm file everything is ok, tail call is optimized.
Try to replace
int x = fac( 50 );
with
int x = fac_aux( 50, 1 );
Strange enough, but tail call optimization is disappeared. As far as I remember there was no such a strange compiler behaviour in VS2008. Any ideas why these things happen and how to be sure of tail call optimization is done?
; Function compile flags: /Ogtp
Tried both /O2 and /Ox optimization flags. Are there any other compiler options that matter?
Edit: VS2012 manages to do the optimization
when the original is compiled, the assembly at the callsite has partial inlining of fac_aux
, specifically the x - 1
part, which is required for the tail recursion, but using fac_aux
prevents the partial inlining and thus the tail recursion optimization:
TestThin.fac_aux 013B1000 CMP ECX,1
013B1003 JE SHORT TestThin.013B100E
013B1005 IMUL EAX,ECX
013B1008 DEC ECX
013B1009 CMP ECX,1
013B100C JNZ SHORT TestThin.013B1005
013B100E RETN
013B100F INT3
TestThin.main 013B1010 MOV EAX,32
013B1015 LEA ECX,DWORD PTR DS:[EAX-1] ;notice the partial inlining of x - 1
013B1018 CALL TestThin.fac_aux
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