Switch Lowering in GCC

(xoranth.net)

87 points | by signa11 4 hours ago ago

15 comments

  • rurban 2 hours ago

    What a shame for clang and gcc! They still don't implement perfect hashes for large sparse switch tables. I did that recently for my rcc C compiler, and it was just a single day of work. Esp. beneficial for unicode work. The LLVM patch was rejected a decade ago. Gcc has several unicode patches sitting in branches, which would also need that

    • RossBencina 38 minutes ago

      Would like to hear more about the performance characteristics. Do you perfect hash to a contiguous range and then use a jump table, or do you perfect hash directly to relative offsets to basic blocks?

    • tester756 an hour ago

      I'd bet because that's probably no better, that's it.

      >The LLVM patch was rejected a decade ago

      And what was the reasoning?

      • ahartmetz 33 minutes ago

        Also you could try again, many things may have changed since then including who maintains the code.

      • rurban 18 minutes ago

        No idea. Most maintainers suck

  • LarsKrimi 2 hours ago

    > The switch in sparse_8 could be simplified by dividing x by eight before the jump. Interestingly, gcc doesn't find this simplification.

    It could not because that would ensure that 7 values for each case would be handled by function calls instead of the default case - 0/8 is 0, but 3/8 is also 0

    • rep_lodsb 40 minutes ago

      All the values are divisible by 8, so it could do it like this:

          cmp  eax,40
          ja   <return 0>
          test eax,7
          jnz  <return 0>
          jmp  JumpTable[rax]
    • Findecanor 20 minutes ago

      Reducing the range would have been useful to reduce the size of a jump table, but when you have a decision tree then it does not matter.

      ... unless the size of immediate parameters would have affected code size. In the example code however, all constants fit in an `imm8` parameter to `cmp`.

  • Andi an hour ago

    I remember having implemented similar things in JavaScript (by generating code), for immutable Maps and Sets - no significant performance gain in modern engines. For regular expressions of complex unicode ranges, the speedup was around 2x!

  • tsukikage 2 hours ago

    Why the indirection? - why not have the jump table reference f0..fX directly rather than jumping to a jump?

  • arsalan17 3 hours ago

    This one was interesting, especially its name :)

  • sylware 2 hours ago

    In order to peak into hardware speculation/BTB, having a look atswitch lowering seems a good way. Big switches will go into serious convolution to please that hardware since by definition this is a source of a lot of branch mispredicitions.

    • ahartmetz 26 minutes ago

      There is surprisingly little about the proper feeding of advanced hardware in that code, two or three constants in cost calculations of which one or two are hardware-dependent.

      It is still possible that a later pass arranges jump targets to avoid false sharing of their entries (addresses) in prediction mechanisms and such.

      • sylware a few seconds ago

        Just look at the assembly output of significantly sized switch statements (with good random values): it's scary :)

        Obvsiously engaging in pleasing as much as it can speculative/BTB hardware (to the cost of memory tables!)