Skip to content

AArch64: Implement switch/jump tables

Sven Tennie requested to merge wip/supersven/aarch64-jump-tables into master

This improves the performance of Cmm switch statements (compared to a chain of if statements.) The implementation is almost identical to that of the RISCV64 NCG.

Example

From CmmSwitchTest64.

Generated Cmm:

u34l: // global
    switch [1 .. 10] _s2wn::I64 {
        case 1 : goto c347;
        case 2 : goto c348;
        case 3 : goto c349;
        case 4 : goto c34a;
        case 5 : goto c34b;
        case 6 : goto c34c;
        case 7 : goto c34d;
        case 8 : goto c34e;
        case 9 : goto c34f;
        case 10 : goto c34g;
    }   // CmmSwitch

Assembly:

.Lu34l:
        ubfm x18, x18, #0, #63
        adrp x17, .Ln34G
        add x17, x17, :lo12:.Ln34G // CmmLit (CmmLabel .Ln34G(other CLabel))
# Jump table for switch
        lsl x18, x18, #3 // CmmReg (CmmLocal (LocalReg s2wn (CmmType BitsCat W64)))
        add x18, x18, x17
        ldr x18, [ x18, 0 ]
        add x18, x18, x17
        br x18

...

.section .rodata
        .balign 8
.Ln34G:
        .quad   0
        .quad   .Lc347-(.Ln34G)+0
        .quad   .Lc348-(.Ln34G)+0
        .quad   .Lc349-(.Ln34G)+0
        .quad   .Lc34a-(.Ln34G)+0
        .quad   .Lc34b-(.Ln34G)+0
        .quad   .Lc34c-(.Ln34G)+0
        .quad   .Lc34d-(.Ln34G)+0
        .quad   .Lc34e-(.Ln34G)+0
        .quad   .Lc34f-(.Ln34G)+0
        .quad   .Lc34g-(.Ln34G)+0

Ticket: #19912

Edited by Sven Tennie

Merge request reports

Loading