Re:F# is gaining independence from .NET
by buybackoff on Monday February 01, 2021 @10:36AM
(#25989546)
Slight correction: .tail prefix prevents inlining by JIT, it's mentioned in the second link in my sibling comment as "explicit tail prefix in callee". So even if that type specialization JIT optimization worked, the small performance-critical method containing it was not inlined. But the point of the specialization was to make the call for primitives faster than a method call, and fallback to a default implementation via callvirt. And there is no way to disable adding the .tail prefix to the calls that do not need it.
This also means that a lot of F# functions that are not inlined by F# source-code inlining itself effectively have NoInlining attribute. E.g. some helper method `if x then y.call() else z.call()`, if not inlined by F#, will never be inlined by JIT due to .tail prefixes before the methods calls.
Also, most simple tail calls are rewritten by a compiler to a loop, but if you look at the generated IL, there are multiple temp variables, locals, needless assignments. Maybe JIT is able to eliminate those, or maybe not... In C# I could get IL that reflects what I write, without surprises.