Skip to content

cmd/compile: recognize continuous runs in switch cases #15780

@josharian

Description

@josharian
package src

func small(i int) bool {
    switch i {
    case 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15: // 9 is only small on a hot day
        return true
    }
    return false
}

func small2(i int) bool {
    switch {
    case 0 <= i && i <= 8, 10 <= i && i <= 15:
        return true
    }
    return false
}

We should compile small to the same code as small2. Instead, we handle each of the cases independently:

"".small t=1 size=112 args=0x10 locals=0x0
"".small2 t=1 size=48 args=0x10 locals=0x0

Worse, we end up paying a significant cost in the SSA backend juggling all the branches and blocks generated by the frontend.

This sounds theoretical, but I keep encountering large switch statements in functions with bad compile times, and I have seen a bunch of contiguous runs. Here's an excerpted example from cmd/vendor/golang.org/x/arch/x86/x86asm:

func gnuArg(inst *Inst, x Arg, usedPrefixes *bool) string {
// ...
        switch inst.Op {
        case CVTSI2SS, CVTSI2SD, CVTSS2SI, CVTSD2SI, CVTTSD2SI, CVTTSS2SI:
            if inst.DataSize == 16 && EAX <= x && x <= R15L {
                x -= EAX - AX
            }
// ...

Those constants all happen to be next to each other.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions