Frame-Pointer Omission /Oy

I just read a post on frame pointer omission (FPO) optimization, also known as /Oy compiler flag. And a comment from Vladimir Scherbina on problems getting the feature actually work. I wondered if there has been any improvement with a Visual Studio .NET 2008 SP1. latest compiler from Microsoft and briefly – the result is yes, the feature seems to be working.

This is the reference code for the feature:

const volatile INT g_nValueA = 0;
const volatile INT g_nValueB = 0;

#pragma optimize("y", off)

__declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE A(const volatile INT& nValue = g_nValueA)
{
	return nValue != 0;
}

#pragma optimize("y", on)

__declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE B(const volatile INT& nValue = g_nValueB)
{
	return nValue != 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	A();
	B();
	return 0;
}

The code is to be compiled in Release and function A is to be not optimized while B is subject for optimization and omitting the frame pointer.

Disassembly shows for A:

__declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE A(const volatile INT& nValue = g_nValueA)
{
00401000  push        ebp
00401001  mov         ebp,esp
	return nValue != 0;
00401003  mov         eax,dword ptr [nValue]
00401006  mov         ecx,dword ptr [eax]
00401008  xor         eax,eax
0040100A  test        ecx,ecx
0040100C  setne       al
}
0040100F  pop         ebp
00401010  ret         4

and for B:

__declspec(dllexport) __declspec(noinline) BOOL STDMETHODCALLTYPE B(const volatile INT& nValue = g_nValueB)
{
	return nValue != 0;
00401020  mov         eax,dword ptr [esp+4]
00401024  mov         ecx,dword ptr [eax]
00401026  xor         eax,eax
00401028  test        ecx,ecx
0040102A  setne       al
}
0040102D  ret         4

and the difference is what was actually expected. It looked as it finally got to work but a check with Visual Studio versions 2003 and 2005 shown that optiomization makes a difference on older versions too.

Leave a Reply