3

I was looking at the double implementation from Reference Source and saw the following function definition:

[Pure]
[System.Runtime.Versioning.NonVersionable]
public static bool IsPositiveInfinity(double d) {
    //Jit will generate inlineable code with this
    if (d == double.PositiveInfinity)
    {
        return true;
    }
    else
    {
        return false;
    }
}

The comment in that excerpt caught my attention. It says:

Jit will generate inlineable code with this

It seems to indicate that the developer expects the following if statement to influence inlining, and as a result is choosing that over a single return line. I understand the concept of JIT inlining (at least, I thought I did) but I don't see how the "if" construct relates to such an operation.

What is the advantage of writing the if in this way in regard to JIT's optimization rules? Is there one, or might this simply be a mistake?

Wasabi Fan
  • 1,763
  • 3
  • 22
  • 36
  • 1
    Seems they didn't care about that for `IsNegative`, `IsInfinity` and `IsNaN` (maybe because those are `unsafe` and therefor handled differently anyway). – René Vogt Jun 02 '17 at 16:32
  • 1
    The comment does not mean what you think it does. In .NET 1.x this method was implemented in the CLR, written in C++. And could thus not be inlined. In .NET 2.0 is was moved into C# code, now it can be inlined. Why the programmer liked this style is hard to guess, a very rough guess is that he liked to to be able to easily set a breakpoint. A lot of the early .NET code is dominated by testability concerns, especially visible in the CLR source. An army of SDETs worked on it. – Hans Passant Jun 02 '17 at 16:40
  • In my version of the compiler, `d == double.PositiveInfinity`, `d == double.PositiveInfinity ? true : false` and the `if` construction all yield different IL. I haven't checked which of these versions get inlined -- I'd sure hope it was all of them, but even if that should be the case, the situation might very well have been different back when this code was written. – Jeroen Mostert Jun 02 '17 at 16:48
  • @Hans Most of the other functions defined in that file use a single `return` line. Do you think that's just a result of different devs' preferences, and no one bothered to normalize it? The rest of the code base is so cleanly formatted that it stands out, but it's believable. – Wasabi Fan Jun 02 '17 at 16:49
  • Testability is my only good guess. .NET 2.0 also included jitters that target x64, Itanium, ARM, Hitachi, Mips and PowerPC. They all use very different floating point models so this code wasn't necessarily trouble-free from day one. – Hans Passant Jun 02 '17 at 17:04
  • 1
    You are asking us to speculate as to the intent of another human being, at the time that they wrote the code, making your question "primarily opinion based". You _might_ gain some insight by studying .NET JIT compiler inlining rules and behavior -- see e.g. https://blogs.msdn.microsoft.com/vancem/2008/08/19/to-inline-or-not-to-inline-that-is-the-question/ and https://stackoverflow.com/q/23850026 -- but it's doubtful the JITter in use at that time is the same as the ones available to study today. If there was a valid optimization back then, it might not even be relevant today. ... – Peter Duniho Jun 02 '17 at 17:32
  • ... and that's not even counting that for any given era of .NET, there's never been just one JIT compiler to consider. – Peter Duniho Jun 02 '17 at 17:33
  • @PeterDuniho I agree that it could be dependent on a particular version, but that doesn't make it a question of opinion. The original developer seemed to claim that there was technical merit to this construction: I would like to know whether there is such a reason, and if so, what that is. Discerning the history of the problem may be part of the answer. I edited the title to make that clear. – Wasabi Fan Jun 02 '17 at 17:47

0 Answers0