Question

I would like to know - will the .NET JITter recursively inline small functions called from other small functions?

Just for example:

public static float Square(float value)
{
    return value * value;
}

public static float Cube(float value)
{
    return Square(value) * value;
}

If I call Cube from somewhere, will it inline all the way, or will I end up with a function call to Square?

And, if so, how deep will it recurse to do the inlining? (Say I were crazy enough to implement a Quartic or Quintic function in the same way.)

Was it helpful?

Solution

Unfortunately you picked a bad example. The x86 JIT compiler doesn't inline methods that return float. Not 100% sure why, I think it does to avoid consistently problems when the float is converted to an 80-bit floating point value in the FPU. Internal precision is 80-bits but those extra bits are sliced off when the 80-bit value is truncated back to a 32-bit value when it is flushed back to memory. Keeping the value in the FPU too long prevents this truncation from happening and changes the calculation result.

If you replace float by double and compile this code:

static void Main(string[] args) {
    Console.WriteLine(Cube(2.0));
}

Then this machine code is generated when the JIT optimizer is enabled:

00000000  push        ebp                             ; setup stack frame
00000001  mov         ebp,esp 
00000003  call        6DA2BEF0                        ; Console.get_Out() 
00000008  fld         qword ptr ds:[010914B0h]        ; ST0 = 8.0
0000000e  sub         esp,8                           ; setup argument for WriteLine
00000011  fstp        qword ptr [esp] 
00000014  mov         ecx,eax                         ; call Console.Out.WriteLine
00000016  mov         eax,dword ptr [ecx] 
00000018  call        dword ptr [eax+000000D0h] 
0000001e  pop         ebp                             ; done
0000001f  ret

Not only did it inline the functions, it was able to evaluate the expressions at compile time. And directly passes the result by calling Console.WriteLine(8.0). Pretty good huh?

Use double, not float.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top