1

I'm trying to check whether a while statement with empty block is being JIT optimized, so I try to run my code at release mode and view the code from Visual Studio's Debug->Windows->Disassembly window. However I'm not seeing any change from the compiled code. I tried to add some statements that I expect to be optimized:

  bool b = false;
    if (b)
                        {
                            new Object();
                        }

but I still see it on the disassembly window:

                        bool b = false;
                        if (b)
                        {
0524A8FF  mov         ecx,dword ptr [ebx+0Ch]  
0524A902  push        dword ptr ds:[33422A0h]  
0524A908  mov         edx,esi  
0524A90A  cmp         dword ptr [ecx],ecx  
0524A90C  call        71DE3490  
0524A911  test        eax,eax  
0524A913  je          0524A97C  
0524A915  mov         ecx,51DEAC4h  
0524A91A  call        002E30F4  
0524A91F  mov         edi,eax  
0524A921  lea         edx,[edi+8]  
0524A924  call        72D12410  
                            new Object();
                        }

I also tried with NGen tool that is mentioned on a related question, but I keep seeing my "junk code" (which I expected to be optimized away), maybe the problem is that I don't write a proper "junk code" that will be optimized away, if that's the case I'd be happy for some better example of code that the JIT should optimize.

How can I add some trivial code that will be optimized for sure and then verify in that disassembly window that the code I added is not there?

BornToCode
  • 9,495
  • 9
  • 66
  • 83
  • Make sure you read all ansewers in duplicate question, not just the accepted one – Evk Oct 16 '17 at 12:21
  • @Evk - do you mean to uncheck "Suppress JIT optimization on module load" & "Enable Just My Code"? I already did that. – BornToCode Oct 16 '17 at 12:39
  • So no answers in duplicate question help you to resolve the problem? – Evk Oct 16 '17 at 12:41
  • @Evk - Unfortunately not. I also tried with Ngen tool that is mentioned in the other answers, but I keep seeing my "junk code" (which I expected to be optimized away), maybe the problem is that I can't write a proper "junk code" that will be optimized away, if that's the case I'd be happy for some better example for code that the JIT should optimize. – BornToCode Oct 16 '17 at 12:57
  • @CodeCaster - I tried to edit my question to point why it's not a dup, could you reopen it (if you think it's appropriate after my edit)? – BornToCode Oct 16 '17 at 16:35
  • If you can edit into your question what you already did. – CodeCaster Oct 16 '17 at 17:43
  • @BornToCode I suggest you use BenchmarkDotNet +Disassembly Diagnoser instead of relying on VS Disassembly. http://adamsitnik.com/Disassembly-Diagnoser/ – Kostya Oct 17 '17 at 11:11
  • @BornToCode Or alternatively you can use WinDbg+SOS but it's a bit more cumbersome then the above method. – Kostya Oct 17 '17 at 11:13

1 Answers1

2

The snippet is not good enough to get a repro. Fleshing it out:

class Program {
    static void Main(string[] args) {
        bool b = false;
        if (b) {
            new object();
        }
    }
 }

Produces:

            bool b = false;
02390450  ret  

That is extreme optimization at work, none of the code survived. The jitter optimizer can tell that b is always false so it doesn't bother generating the constructor call. Dead code elimination is one of the optimization strategies.

I tried to add some statements that I expect to be optimized

That was the problem, you cannot see any side-effect of added statements that don't produce any code. All that is there is the machine code produced by the original code.

Do beware that the source annotations that are visible in the Disassembly window are only accurate when you use the Debug build. In the optimized Release build they can get pretty bewildering wrong due to the optimizer moving and deleting code.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • When I copied your code to a new small Console app I saw you're correct and it was optimized. When I tried to embed the `bool b = false; if (b) { new object(); }` part to my big real application (and ran it with release config, optimization enabled) the dead code wasn't eliminated. I don't understand why? – BornToCode Oct 17 '17 at 15:25
  • 1
    You are still missing the point, none of the machine code in your question was generated by the added code. There is no added code. We can't see the statement that appears before it, but I'd guess at an expression that uses the conditional operator. The kind of very dense expression that gives the jitter a throbbing headache when it needs to generate debugger info from the optimized code. Which is why the source annotation appears in the wrong place. Always keep in mind that debug info is very imperfect for Release built code, it is the very reason why a Debug configuration exists at all. – Hans Passant Oct 17 '17 at 15:32