Skip to content

clang generating compare-branch(binary-tree) for a large switch statement #98223

Open
@appujee

Description

@appujee

It makes sense for a couple of cases but this one has a dozen case statements and I wonder why clang assumes that binary-tree is better?

#include<cstring>
#include<wctype.h>

enum {
  WC_TYPE_INVALID = 0,
  WC_TYPE_ALNUM,
  WC_TYPE_ALPHA,
  WC_TYPE_BLANK,
  WC_TYPE_CNTRL,
  WC_TYPE_DIGIT,
  WC_TYPE_GRAPH,
  WC_TYPE_LOWER,
  WC_TYPE_PRINT,
  WC_TYPE_PUNCT,
  WC_TYPE_SPACE,
  WC_TYPE_UPPER,
  WC_TYPE_XDIGIT,
  WC_TYPE_MAX
};

int iswctype(wint_t wc, wctype_t char_class) {
  switch (char_class) {
    case WC_TYPE_ALNUM: return iswalnum(wc);
    case WC_TYPE_ALPHA: return iswalpha(wc);
    case WC_TYPE_BLANK: return iswblank(wc);
    case WC_TYPE_CNTRL: return iswcntrl(wc);
    case WC_TYPE_DIGIT: return iswdigit(wc);
    case WC_TYPE_GRAPH: return iswgraph(wc);
    case WC_TYPE_LOWER: return iswlower(wc);
    case WC_TYPE_PRINT: return iswprint(wc);
    case WC_TYPE_PUNCT: return iswpunct(wc);
    case WC_TYPE_SPACE: return iswspace(wc);
    case WC_TYPE_UPPER: return iswupper(wc);
    case WC_TYPE_XDIGIT: return iswxdigit(wc);
    default: return 0;
  }
}

https://godbolt.org/z/jzx33W9Mx

iswctype:                               // @iswctype
        cmp     x1, #6
        b.gt    .LBB0_6
        cmp     x1, #3
        b.gt    .LBB0_11
        cmp     x1, #1
        b.eq    .LBB0_19
        cmp     x1, #2
        b.eq    .LBB0_23
        cmp     x1, #3
        b.ne    .LBB0_27
        b       iswblank
.LBB0_6:
        cmp     x1, #9
        b.gt    .LBB0_15
        cmp     x1, #7
        b.eq    .LBB0_20
        cmp     x1, #8
        b.eq    .LBB0_24
        cmp     x1, #9
        b.ne    .LBB0_27
        b       iswpunct
.LBB0_11:
        cmp     x1, #4
        b.eq    .LBB0_21
        cmp     x1, #5
        b.eq    .LBB0_25
        cmp     x1, #6
        b.ne    .LBB0_27
        b       iswgraph
.LBB0_15:
        cmp     x1, #10
        b.eq    .LBB0_22
        cmp     x1, #11
        b.eq    .LBB0_26
        cmp     x1, #12
        b.ne    .LBB0_27
        b       iswxdigit
.LBB0_19:
        b       iswalnum
.LBB0_20:
        b       iswlower
.LBB0_21:
        b       iswcntrl
.LBB0_22:
        b       iswspace
.LBB0_23:
        b       iswalpha
.LBB0_24:
        b       iswprint
.LBB0_25:
        b       iswdigit
.LBB0_26:
        b       iswupper
.LBB0_27:
        mov     w0, wzr
        ret

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions