We manually partially inline utf8.DecodeRune in a few places in the tree. For example, in bytes.EqualFold, we have:

        if s[0] < utf8.RuneSelf {
            sr, s = rune(s[0]), s[1:]
        } else {
            r, size := utf8.DecodeRune(s)
            sr, s = r, s[size:]
        }

It'd be nice to rewrite utf8.DecodeRune like this:

func DecodeRune(p []byte) (r rune, size int) {
    if len(p) > 0 && p[0] < RuneSelf {
        return rune(p[0]), 1
    }
    return decodeRuneSlow(p)
}

and then let mid-stack inlining take it from there. (And delete all the manual partial inlining.)

Unfortunately, this has a cost of 89, over the budget of 80.

This is basically just another variant of https://github.com/golang/go/issues/17566, but I'm filing it separately since that issue is super noisy.

cc @bradfitz @mvdan @dr2chase

Comment From: martisch

While at it we should make it also work for utf8.DecodeRuneInString at the same time.

Comment From: mvdan

Perhaps very clear cases like this can be used to start tweaking the inlining heuristic in the right direction, with the smallest steps possible.

Comment From: corona10

@martisch @mvdan Can I take a look at this issue?

Comment From: mvdan

@corona10 you're certainly welcome to take a look, but if you're looking for low-hanging fruit issues to work on, this isn't a good candidate. It likely requires someone with a good understanding of the compiler, and it's not a simple fix, as @josharian already gave that a try.

Comment From: corona10

@mvdan Oh.. @josharian already tried it. Looks like a not simple issue. I thought it was just an issue of rewriting so that it can help the compiler to do a mid stack inlining, but I did not know that cost was an issue to consider. I will try to find some easier issues.

Comment From: renthraysk

binary.Uvarint() has the same problem. Impossible to write the 1 byte fast path mid stack func without exceeding cost.

Comment From: gopherbot

Change https://go.dev/cl/425459 mentions this issue: bytes/strings: add ASCII fast path to EqualFold

Comment From: jub0bs

@martisch

While at it we should make it also work for utf8.DecodeRuneInString at the same time.

See https://github.com/golang/go/issues/48195#issuecomment-3224273708