Skip to content

cmd/compile: do front-end constant evaluation across simple inlined function boundaries #16108

Open
@josharian

Description

@josharian
func i(x int) int { return x }

func f(a int) bool {
    switch a {
    case 1, 2, 3, 4, 5, 6:
        return true
    }
    return false
}

func g(a int) bool {
    switch a {
    case i(1), i(2), i(3), i(4), i(5), i(6):
        return true
    }
    return false
}

f and g should compile to the same code. They don't. In g, i(n) is not recognized as a constant case, because i(n) ends up being a tempname introduced to hold the inlined return value from i. As a result, g does not use binary search over the cases. The SSA back-end can see past such things, but several important optimization decisions are made in the front-end on a const/non-const basis.

As a first pass, maybe recognized inlined functions containing exactly one return statement and inline the returned expression directly. This may also require work to avoid converting inlined arguments from constants to tempnames, which itself might be useful.

Sample real world code in which this occurs, from asm9.go in the s390x obj code:

func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
    return o<<26 | xo<<1 | oe<<10 | rc&1
}

func opform(ctxt *obj.Link, insn uint32) int {
    switch insn {
    default:
        ctxt.Diag("bad insn in loadform: %x", insn)
    case OPVCC(58, 0, 0, 0), // ld
        OPVCC(58, 0, 0, 0) | 1<<1, // lwa
        OPVCC(62, 0, 0, 0):        // std
        return DS_FORM
    case OP_ADDI, // add
        OPVCC(32, 0, 0, 0), // lwz
        OPVCC(42, 0, 0, 0), // lha
        OPVCC(40, 0, 0, 0), // lhz
        OPVCC(34, 0, 0, 0), // lbz
        OPVCC(50, 0, 0, 0), // lfd
        OPVCC(48, 0, 0, 0), // lfs
        OPVCC(36, 0, 0, 0), // stw
        OPVCC(44, 0, 0, 0), // sth
        OPVCC(38, 0, 0, 0), // stb
        OPVCC(54, 0, 0, 0), // stfd
        OPVCC(52, 0, 0, 0): // stfs
        return D_FORM
    }
    return 0
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsFixThe path to resolution is known, but the work has not been done.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions