On Thu, 28 Feb 2013 12:13:27 -0500, Dmitry Olshansky <[email protected]> wrote:

No as a compiler will take it (or may depending on its brain) that 0 is what you want to test *first*. It may speed things up if branch is almost always taken but its not the case with sentinel. Thus its jsut dead code that needs to be decoded, evalutated and skipped (as predicated) *before* doing switch jump.

Well, according to lexer.c, case 0 is the first case. Why does that not make the compiler decide to test 0 first?

Answer: it actually doesn't care, the switch compiles to a jump table. Which still begs the question, why can't the compiler make the leap to the equivalent code with a range?

are these not semantically equivalent?

if(x == 0)
{
   // case for 0
}
else
{
   switch(x)
   {
      case 1:
         // case for 1;
         break;
      case 2:
         // case for 2;
         break;
      ... // cases for everything but 0
   }
}

vs.

switch(x)
{
   case 0:
      // case for 0;
      break;
   case 1:
      // case for 1;
      break;
   case 2:
      // case for 2;
      break;
   ... // cases for everything but 0
}

They seem semantically identical. It would not be impossible for an optimizer to make this leap.

Combined with inlining, the above could be:

if(r.empty)
{
   // case for 0;
}
else
  ...

and still be optimized the same. I'm not saying it happens, I'm saying it's possible. I have read several posts here claiming that llvm does this (I haven't tried this myself, but it sounds likely true).

-Steve

Reply via email to