2017-09-13 15:04:16 +02:00
|
|
|
// Copyright 2017 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
2020-12-23 01:09:46 -05:00
|
|
|
package test
|
2017-09-13 15:04:16 +02:00
|
|
|
|
|
|
|
|
import (
|
2017-09-14 15:51:18 +01:00
|
|
|
"bufio"
|
2022-10-10 13:39:30 -04:00
|
|
|
"internal/goexperiment"
|
2017-09-13 15:04:16 +02:00
|
|
|
"internal/testenv"
|
2017-09-14 15:51:18 +01:00
|
|
|
"io"
|
2019-03-09 17:48:23 +00:00
|
|
|
"math/bits"
|
2017-09-14 15:51:18 +01:00
|
|
|
"regexp"
|
2017-09-20 13:09:08 -05:00
|
|
|
"runtime"
|
2017-09-14 15:51:18 +01:00
|
|
|
"strings"
|
2017-09-13 15:04:16 +02:00
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
2021-02-11 10:49:55 -08:00
|
|
|
// TestIntendedInlining tests that specific functions are inlined.
|
2017-09-13 15:04:16 +02:00
|
|
|
// This allows refactoring for code clarity and re-use without fear that
|
|
|
|
|
// changes to the compiler will cause silent performance regressions.
|
|
|
|
|
func TestIntendedInlining(t *testing.T) {
|
|
|
|
|
if testing.Short() && testenv.Builder() == "" {
|
|
|
|
|
t.Skip("skipping in short mode")
|
|
|
|
|
}
|
|
|
|
|
testenv.MustHaveGoRun(t)
|
|
|
|
|
t.Parallel()
|
|
|
|
|
|
2017-09-13 21:03:20 +02:00
|
|
|
// want is the list of function names (by package) that should
|
2019-02-22 15:53:52 +00:00
|
|
|
// be inlinable. If they have no callers in their packages, they
|
2018-09-17 14:08:03 -05:00
|
|
|
// might not actually be inlined anywhere.
|
2017-09-13 21:03:20 +02:00
|
|
|
want := map[string][]string{
|
|
|
|
|
"runtime": {
|
|
|
|
|
"add",
|
2017-09-23 21:44:18 +01:00
|
|
|
"acquirem",
|
|
|
|
|
"add1",
|
2017-09-13 21:03:20 +02:00
|
|
|
"addb",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"adjustpanics",
|
|
|
|
|
"adjustpointer",
|
2019-06-28 16:44:07 +00:00
|
|
|
"alignDown",
|
|
|
|
|
"alignUp",
|
2017-09-13 21:03:20 +02:00
|
|
|
"bucketMask",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"bucketShift",
|
|
|
|
|
"chanbuf",
|
|
|
|
|
"evacuated",
|
|
|
|
|
"fastlog2",
|
2017-09-13 21:03:20 +02:00
|
|
|
"fastrand",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"float64bits",
|
2021-10-06 12:24:59 -07:00
|
|
|
"funcspdelta",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"getm",
|
2020-11-02 16:58:38 +00:00
|
|
|
"getMCache",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"isDirectIface",
|
|
|
|
|
"itabHashFunc",
|
2017-09-13 21:03:20 +02:00
|
|
|
"noescape",
|
runtime: reduce linear search through pcvalue cache
This change introduces two optimizations together,
one for recursive and one for non-recursive stacks.
For recursive stacks, we introduce the new entry
at the beginning of the cache, so it can be found first.
This adds an extra read and write.
While we're here, switch from fastrandn, which does a multiply,
to fastrand % n, which does a shift.
For non-recursive stacks, split the cache from [16]pcvalueCacheEnt
into [2][8]pcvalueCacheEnt, and add a very cheap associative lookup.
name old time/op new time/op delta
StackCopyPtr-8 118ms ± 1% 106ms ± 2% -9.56% (p=0.000 n=17+18)
StackCopy-8 95.8ms ± 1% 87.0ms ± 3% -9.11% (p=0.000 n=19+20)
StackCopyNoCache-8 135ms ± 2% 139ms ± 1% +3.06% (p=0.000 n=19+18)
During make.bash, the association function used has this return distribution:
percent count return value
53.23% 678797 1
46.74% 596094 0
It is definitely not perfect, but it is pretty good,
and that's all we need.
Change-Id: I2cabb1d26b99c5111bc28f427016a2a5e6c620fd
Reviewed-on: https://go-review.googlesource.com/c/110564
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2018-04-01 16:39:34 -07:00
|
|
|
"pcvalueCacheKey",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"readUnaligned32",
|
|
|
|
|
"readUnaligned64",
|
2017-09-23 21:44:18 +01:00
|
|
|
"releasem",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"roundupsize",
|
2018-04-01 12:21:57 -07:00
|
|
|
"stackmapdata",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"stringStructOf",
|
2017-09-23 21:44:18 +01:00
|
|
|
"subtract1",
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"subtractb",
|
|
|
|
|
"tophash",
|
|
|
|
|
"(*bmap).keys",
|
|
|
|
|
"(*bmap).overflow",
|
|
|
|
|
"(*waitq).enqueue",
|
2021-09-21 14:22:51 -07:00
|
|
|
"funcInfo.entry",
|
2017-09-23 21:44:18 +01:00
|
|
|
|
|
|
|
|
// GC-related ones
|
|
|
|
|
"cgoInRange",
|
|
|
|
|
"gclinkptr.ptr",
|
|
|
|
|
"guintptr.ptr",
|
2022-04-29 13:21:44 -07:00
|
|
|
"writeHeapBitsForAddr",
|
2017-09-23 21:44:18 +01:00
|
|
|
"markBits.isMarked",
|
|
|
|
|
"muintptr.ptr",
|
|
|
|
|
"puintptr.ptr",
|
2018-02-16 17:45:21 -05:00
|
|
|
"spanOf",
|
2017-09-23 21:44:18 +01:00
|
|
|
"spanOfUnchecked",
|
2020-10-14 17:18:27 -04:00
|
|
|
"(*gcWork).putFast",
|
2017-09-23 21:44:18 +01:00
|
|
|
"(*gcWork).tryGetFast",
|
|
|
|
|
"(*guintptr).set",
|
|
|
|
|
"(*markBits).advance",
|
|
|
|
|
"(*mspan).allocBitsForIndex",
|
|
|
|
|
"(*mspan).base",
|
|
|
|
|
"(*mspan).markBitsForBase",
|
|
|
|
|
"(*mspan).markBitsForIndex",
|
|
|
|
|
"(*muintptr).set",
|
|
|
|
|
"(*puintptr).set",
|
2022-10-25 17:58:07 -07:00
|
|
|
"(*wbBuf).get1",
|
|
|
|
|
"(*wbBuf).get2",
|
2017-09-13 21:03:20 +02:00
|
|
|
},
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
"runtime/internal/sys": {},
|
2018-01-27 11:55:34 +01:00
|
|
|
"runtime/internal/math": {
|
|
|
|
|
"MulUintptr",
|
|
|
|
|
},
|
2017-09-24 17:55:19 +01:00
|
|
|
"bytes": {
|
|
|
|
|
"(*Buffer).Bytes",
|
|
|
|
|
"(*Buffer).Cap",
|
|
|
|
|
"(*Buffer).Len",
|
2018-12-01 16:28:27 +00:00
|
|
|
"(*Buffer).Grow",
|
2017-09-24 17:55:19 +01:00
|
|
|
"(*Buffer).Next",
|
|
|
|
|
"(*Buffer).Read",
|
|
|
|
|
"(*Buffer).ReadByte",
|
|
|
|
|
"(*Buffer).Reset",
|
|
|
|
|
"(*Buffer).String",
|
|
|
|
|
"(*Buffer).UnreadByte",
|
|
|
|
|
"(*Buffer).tryGrowByReslice",
|
|
|
|
|
},
|
2018-09-17 14:08:03 -05:00
|
|
|
"compress/flate": {
|
|
|
|
|
"byLiteral.Len",
|
|
|
|
|
"byLiteral.Less",
|
|
|
|
|
"byLiteral.Swap",
|
2020-10-16 15:05:04 +01:00
|
|
|
"(*dictDecoder).tryWriteCopy",
|
2018-09-17 14:08:03 -05:00
|
|
|
},
|
encoding/base64: speed up the decoder
Most of the decoding time is spent in the first Decode loop, since the
rest of the function only deals with the few remaining bytes. Any
unnecessary work done in that loop body matters tremendously.
One such unnecessary bottleneck was the use of the enc.decodeMap table.
Since enc is a pointer receiver, and the field is used within the
non-inlineable function decode64, the decoder must perform a nil check
at every iteration.
To fix that, move the enc.decodeMap uses to the parent function, where
we can lift the nil check outside the loop. That gives roughly a 15%
speed-up. The function no longer performs decoding per se, so rename it.
While at it, remove the now unnecessary receivers.
An unfortunate side effect of this change is that the loop now contains
eight bounds checks on src instead of just one. However, not having to
slice src plus the nil check removal well outweigh the added cost.
The other piece that made decode64 slow was that it wasn't inlined, and
had multiple branches. Use a simple bitwise-or trick suggested by Roger
Peppe, and collapse the rest of the bitwise logic into a single
expression. Inlinability and the reduced branching give a further 10%
speed-up.
Finally, add these two functions to TestIntendedInlining, since we want
them to stay inlinable.
Apply the same refactor to decode32 for consistency, and to let 32-bit
architectures see a similar performance gain for large inputs.
name old time/op new time/op delta
DecodeString/2-8 47.3ns ± 1% 45.8ns ± 0% -3.28% (p=0.002 n=6+6)
DecodeString/4-8 55.8ns ± 2% 51.5ns ± 0% -7.71% (p=0.004 n=5+6)
DecodeString/8-8 64.9ns ± 0% 61.7ns ± 0% -4.99% (p=0.004 n=5+6)
DecodeString/64-8 238ns ± 0% 198ns ± 0% -16.54% (p=0.002 n=6+6)
DecodeString/8192-8 19.5µs ± 0% 14.6µs ± 0% -24.96% (p=0.004 n=6+5)
name old speed new speed delta
DecodeString/2-8 84.6MB/s ± 1% 87.4MB/s ± 0% +3.38% (p=0.002 n=6+6)
DecodeString/4-8 143MB/s ± 2% 155MB/s ± 0% +8.41% (p=0.004 n=5+6)
DecodeString/8-8 185MB/s ± 0% 195MB/s ± 0% +5.29% (p=0.004 n=5+6)
DecodeString/64-8 369MB/s ± 0% 442MB/s ± 0% +19.78% (p=0.002 n=6+6)
DecodeString/8192-8 560MB/s ± 0% 746MB/s ± 0% +33.27% (p=0.004 n=6+5)
Updates #19636.
Change-Id: Ib839577b0e3f5a2bb201f5cae580c61365d92894
Reviewed-on: https://go-review.googlesource.com/c/go/+/151177
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: roger peppe <rogpeppe@gmail.com>
2018-11-25 17:30:36 +00:00
|
|
|
"encoding/base64": {
|
|
|
|
|
"assemble32",
|
|
|
|
|
"assemble64",
|
|
|
|
|
},
|
2017-09-13 21:03:20 +02:00
|
|
|
"unicode/utf8": {
|
|
|
|
|
"FullRune",
|
|
|
|
|
"FullRuneInString",
|
|
|
|
|
"RuneLen",
|
2021-08-11 23:51:09 -07:00
|
|
|
"AppendRune",
|
2017-09-13 21:03:20 +02:00
|
|
|
"ValidRune",
|
|
|
|
|
},
|
2022-11-25 14:22:36 +01:00
|
|
|
"unicode/utf16": {
|
|
|
|
|
"Decode",
|
|
|
|
|
},
|
2017-09-28 20:44:21 +01:00
|
|
|
"reflect": {
|
reflect: make more Value methods inlineable
The following Value methods are now inlineable:
Bool for ~bool
String for ~string (but not other kinds)
Bytes for []byte (but not ~[]byte or ~[N]byte)
Len for ~[]T (but not ~[N]T, ~chan T, ~map[K]V, or ~string)
Cap for ~[]T (but not ~[N]T or ~chan T)
For Bytes, we only have enough inline budget to inline one type,
so we optimize for unnamed []byte, which is far more common than
named []byte or [N]byte.
For Len and Cap, we only have enough inline budget to inline one kind,
so we optimize for ~[]T, which is more common than the others.
The exception is string, but the size of a string can be obtained
through len(v.String()).
Performance:
Bool 1.65ns ± 0% 0.51ns ± 3% -68.81% (p=0.008 n=5+5)
String 1.97ns ± 1% 0.70ns ± 1% -64.25% (p=0.008 n=5+5)
Bytes 8.90ns ± 2% 0.89ns ± 1% -89.95% (p=0.008 n=5+5)
NamedBytes 8.89ns ± 1% 8.88ns ± 1% ~ (p=0.548 n=5+5)
BytesArray 10.0ns ± 2% 10.2ns ± 1% +1.58% (p=0.048 n=5+5)
SliceLen 1.97ns ± 1% 0.45ns ± 1% -77.22% (p=0.008 n=5+5)
MapLen 2.62ns ± 1% 3.07ns ± 1% +17.24% (p=0.008 n=5+5)
StringLen 1.96ns ± 1% 1.98ns ± 2% ~ (p=0.151 n=5+5)
ArrayLen 1.96ns ± 1% 2.19ns ± 1% +11.46% (p=0.008 n=5+5)
SliceCap 1.76ns ± 1% 0.45ns ± 2% -74.28% (p=0.008 n=5+5)
There's a slight slowdown (~10-20%) for obtaining the length
of a string or map, but a substantial improvement for slices.
Performance according to encoding/json:
CodeMarshal 555µs ± 2% 562µs ± 4% ~ (p=0.421 n=5+5)
MarshalBytes/32 163ns ± 1% 157ns ± 1% -3.82% (p=0.008 n=5+5)
MarshalBytes/256 453ns ± 1% 447ns ± 1% ~ (p=0.056 n=5+5)
MarshalBytes/4096 4.10µs ± 1% 4.09µs ± 0% ~ (p=1.000 n=5+4)
CodeUnmarshal 3.16ms ± 2% 3.02ms ± 1% -4.18% (p=0.008 n=5+5)
CodeUnmarshalReuse 2.64ms ± 3% 2.51ms ± 2% -4.81% (p=0.016 n=5+5)
UnmarshalString 65.4ns ± 4% 64.1ns ± 0% ~ (p=0.190 n=5+4)
UnmarshalFloat64 59.8ns ± 5% 58.9ns ± 2% ~ (p=0.222 n=5+5)
UnmarshalInt64 51.7ns ± 1% 50.0ns ± 2% -3.26% (p=0.008 n=5+5)
EncodeMarshaler 23.6ns ±11% 20.8ns ± 1% -12.10% (p=0.016 n=5+4)
Add all inlineable methods of Value to cmd/compile/internal/test/inl_test.go.
Change-Id: Ifc192491918af6b62f7fe3a094a5a5256bfb326d
Reviewed-on: https://go-review.googlesource.com/c/go/+/400676
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-16 19:01:48 -07:00
|
|
|
"Value.Bool",
|
|
|
|
|
"Value.Bytes",
|
2017-09-28 20:44:21 +01:00
|
|
|
"Value.CanAddr",
|
reflect: make more Value methods inlineable
The following Value methods are now inlineable:
Bool for ~bool
String for ~string (but not other kinds)
Bytes for []byte (but not ~[]byte or ~[N]byte)
Len for ~[]T (but not ~[N]T, ~chan T, ~map[K]V, or ~string)
Cap for ~[]T (but not ~[N]T or ~chan T)
For Bytes, we only have enough inline budget to inline one type,
so we optimize for unnamed []byte, which is far more common than
named []byte or [N]byte.
For Len and Cap, we only have enough inline budget to inline one kind,
so we optimize for ~[]T, which is more common than the others.
The exception is string, but the size of a string can be obtained
through len(v.String()).
Performance:
Bool 1.65ns ± 0% 0.51ns ± 3% -68.81% (p=0.008 n=5+5)
String 1.97ns ± 1% 0.70ns ± 1% -64.25% (p=0.008 n=5+5)
Bytes 8.90ns ± 2% 0.89ns ± 1% -89.95% (p=0.008 n=5+5)
NamedBytes 8.89ns ± 1% 8.88ns ± 1% ~ (p=0.548 n=5+5)
BytesArray 10.0ns ± 2% 10.2ns ± 1% +1.58% (p=0.048 n=5+5)
SliceLen 1.97ns ± 1% 0.45ns ± 1% -77.22% (p=0.008 n=5+5)
MapLen 2.62ns ± 1% 3.07ns ± 1% +17.24% (p=0.008 n=5+5)
StringLen 1.96ns ± 1% 1.98ns ± 2% ~ (p=0.151 n=5+5)
ArrayLen 1.96ns ± 1% 2.19ns ± 1% +11.46% (p=0.008 n=5+5)
SliceCap 1.76ns ± 1% 0.45ns ± 2% -74.28% (p=0.008 n=5+5)
There's a slight slowdown (~10-20%) for obtaining the length
of a string or map, but a substantial improvement for slices.
Performance according to encoding/json:
CodeMarshal 555µs ± 2% 562µs ± 4% ~ (p=0.421 n=5+5)
MarshalBytes/32 163ns ± 1% 157ns ± 1% -3.82% (p=0.008 n=5+5)
MarshalBytes/256 453ns ± 1% 447ns ± 1% ~ (p=0.056 n=5+5)
MarshalBytes/4096 4.10µs ± 1% 4.09µs ± 0% ~ (p=1.000 n=5+4)
CodeUnmarshal 3.16ms ± 2% 3.02ms ± 1% -4.18% (p=0.008 n=5+5)
CodeUnmarshalReuse 2.64ms ± 3% 2.51ms ± 2% -4.81% (p=0.016 n=5+5)
UnmarshalString 65.4ns ± 4% 64.1ns ± 0% ~ (p=0.190 n=5+4)
UnmarshalFloat64 59.8ns ± 5% 58.9ns ± 2% ~ (p=0.222 n=5+5)
UnmarshalInt64 51.7ns ± 1% 50.0ns ± 2% -3.26% (p=0.008 n=5+5)
EncodeMarshaler 23.6ns ±11% 20.8ns ± 1% -12.10% (p=0.016 n=5+4)
Add all inlineable methods of Value to cmd/compile/internal/test/inl_test.go.
Change-Id: Ifc192491918af6b62f7fe3a094a5a5256bfb326d
Reviewed-on: https://go-review.googlesource.com/c/go/+/400676
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-16 19:01:48 -07:00
|
|
|
"Value.CanComplex",
|
|
|
|
|
"Value.CanFloat",
|
|
|
|
|
"Value.CanInt",
|
2019-03-09 17:48:23 +00:00
|
|
|
"Value.CanInterface",
|
reflect: make more Value methods inlineable
The following Value methods are now inlineable:
Bool for ~bool
String for ~string (but not other kinds)
Bytes for []byte (but not ~[]byte or ~[N]byte)
Len for ~[]T (but not ~[N]T, ~chan T, ~map[K]V, or ~string)
Cap for ~[]T (but not ~[N]T or ~chan T)
For Bytes, we only have enough inline budget to inline one type,
so we optimize for unnamed []byte, which is far more common than
named []byte or [N]byte.
For Len and Cap, we only have enough inline budget to inline one kind,
so we optimize for ~[]T, which is more common than the others.
The exception is string, but the size of a string can be obtained
through len(v.String()).
Performance:
Bool 1.65ns ± 0% 0.51ns ± 3% -68.81% (p=0.008 n=5+5)
String 1.97ns ± 1% 0.70ns ± 1% -64.25% (p=0.008 n=5+5)
Bytes 8.90ns ± 2% 0.89ns ± 1% -89.95% (p=0.008 n=5+5)
NamedBytes 8.89ns ± 1% 8.88ns ± 1% ~ (p=0.548 n=5+5)
BytesArray 10.0ns ± 2% 10.2ns ± 1% +1.58% (p=0.048 n=5+5)
SliceLen 1.97ns ± 1% 0.45ns ± 1% -77.22% (p=0.008 n=5+5)
MapLen 2.62ns ± 1% 3.07ns ± 1% +17.24% (p=0.008 n=5+5)
StringLen 1.96ns ± 1% 1.98ns ± 2% ~ (p=0.151 n=5+5)
ArrayLen 1.96ns ± 1% 2.19ns ± 1% +11.46% (p=0.008 n=5+5)
SliceCap 1.76ns ± 1% 0.45ns ± 2% -74.28% (p=0.008 n=5+5)
There's a slight slowdown (~10-20%) for obtaining the length
of a string or map, but a substantial improvement for slices.
Performance according to encoding/json:
CodeMarshal 555µs ± 2% 562µs ± 4% ~ (p=0.421 n=5+5)
MarshalBytes/32 163ns ± 1% 157ns ± 1% -3.82% (p=0.008 n=5+5)
MarshalBytes/256 453ns ± 1% 447ns ± 1% ~ (p=0.056 n=5+5)
MarshalBytes/4096 4.10µs ± 1% 4.09µs ± 0% ~ (p=1.000 n=5+4)
CodeUnmarshal 3.16ms ± 2% 3.02ms ± 1% -4.18% (p=0.008 n=5+5)
CodeUnmarshalReuse 2.64ms ± 3% 2.51ms ± 2% -4.81% (p=0.016 n=5+5)
UnmarshalString 65.4ns ± 4% 64.1ns ± 0% ~ (p=0.190 n=5+4)
UnmarshalFloat64 59.8ns ± 5% 58.9ns ± 2% ~ (p=0.222 n=5+5)
UnmarshalInt64 51.7ns ± 1% 50.0ns ± 2% -3.26% (p=0.008 n=5+5)
EncodeMarshaler 23.6ns ±11% 20.8ns ± 1% -12.10% (p=0.016 n=5+4)
Add all inlineable methods of Value to cmd/compile/internal/test/inl_test.go.
Change-Id: Ifc192491918af6b62f7fe3a094a5a5256bfb326d
Reviewed-on: https://go-review.googlesource.com/c/go/+/400676
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-16 19:01:48 -07:00
|
|
|
"Value.CanSet",
|
|
|
|
|
"Value.CanUint",
|
|
|
|
|
"Value.Cap",
|
|
|
|
|
"Value.Complex",
|
|
|
|
|
"Value.Float",
|
|
|
|
|
"Value.Int",
|
|
|
|
|
"Value.Interface",
|
|
|
|
|
"Value.IsNil",
|
2017-09-28 20:44:21 +01:00
|
|
|
"Value.IsValid",
|
reflect: make more Value methods inlineable
The following Value methods are now inlineable:
Bool for ~bool
String for ~string (but not other kinds)
Bytes for []byte (but not ~[]byte or ~[N]byte)
Len for ~[]T (but not ~[N]T, ~chan T, ~map[K]V, or ~string)
Cap for ~[]T (but not ~[N]T or ~chan T)
For Bytes, we only have enough inline budget to inline one type,
so we optimize for unnamed []byte, which is far more common than
named []byte or [N]byte.
For Len and Cap, we only have enough inline budget to inline one kind,
so we optimize for ~[]T, which is more common than the others.
The exception is string, but the size of a string can be obtained
through len(v.String()).
Performance:
Bool 1.65ns ± 0% 0.51ns ± 3% -68.81% (p=0.008 n=5+5)
String 1.97ns ± 1% 0.70ns ± 1% -64.25% (p=0.008 n=5+5)
Bytes 8.90ns ± 2% 0.89ns ± 1% -89.95% (p=0.008 n=5+5)
NamedBytes 8.89ns ± 1% 8.88ns ± 1% ~ (p=0.548 n=5+5)
BytesArray 10.0ns ± 2% 10.2ns ± 1% +1.58% (p=0.048 n=5+5)
SliceLen 1.97ns ± 1% 0.45ns ± 1% -77.22% (p=0.008 n=5+5)
MapLen 2.62ns ± 1% 3.07ns ± 1% +17.24% (p=0.008 n=5+5)
StringLen 1.96ns ± 1% 1.98ns ± 2% ~ (p=0.151 n=5+5)
ArrayLen 1.96ns ± 1% 2.19ns ± 1% +11.46% (p=0.008 n=5+5)
SliceCap 1.76ns ± 1% 0.45ns ± 2% -74.28% (p=0.008 n=5+5)
There's a slight slowdown (~10-20%) for obtaining the length
of a string or map, but a substantial improvement for slices.
Performance according to encoding/json:
CodeMarshal 555µs ± 2% 562µs ± 4% ~ (p=0.421 n=5+5)
MarshalBytes/32 163ns ± 1% 157ns ± 1% -3.82% (p=0.008 n=5+5)
MarshalBytes/256 453ns ± 1% 447ns ± 1% ~ (p=0.056 n=5+5)
MarshalBytes/4096 4.10µs ± 1% 4.09µs ± 0% ~ (p=1.000 n=5+4)
CodeUnmarshal 3.16ms ± 2% 3.02ms ± 1% -4.18% (p=0.008 n=5+5)
CodeUnmarshalReuse 2.64ms ± 3% 2.51ms ± 2% -4.81% (p=0.016 n=5+5)
UnmarshalString 65.4ns ± 4% 64.1ns ± 0% ~ (p=0.190 n=5+4)
UnmarshalFloat64 59.8ns ± 5% 58.9ns ± 2% ~ (p=0.222 n=5+5)
UnmarshalInt64 51.7ns ± 1% 50.0ns ± 2% -3.26% (p=0.008 n=5+5)
EncodeMarshaler 23.6ns ±11% 20.8ns ± 1% -12.10% (p=0.016 n=5+4)
Add all inlineable methods of Value to cmd/compile/internal/test/inl_test.go.
Change-Id: Ifc192491918af6b62f7fe3a094a5a5256bfb326d
Reviewed-on: https://go-review.googlesource.com/c/go/+/400676
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-16 19:01:48 -07:00
|
|
|
"Value.Kind",
|
|
|
|
|
"Value.Len",
|
2022-04-16 20:23:28 -07:00
|
|
|
"Value.MapRange",
|
reflect: make more Value methods inlineable
The following Value methods are now inlineable:
Bool for ~bool
String for ~string (but not other kinds)
Bytes for []byte (but not ~[]byte or ~[N]byte)
Len for ~[]T (but not ~[N]T, ~chan T, ~map[K]V, or ~string)
Cap for ~[]T (but not ~[N]T or ~chan T)
For Bytes, we only have enough inline budget to inline one type,
so we optimize for unnamed []byte, which is far more common than
named []byte or [N]byte.
For Len and Cap, we only have enough inline budget to inline one kind,
so we optimize for ~[]T, which is more common than the others.
The exception is string, but the size of a string can be obtained
through len(v.String()).
Performance:
Bool 1.65ns ± 0% 0.51ns ± 3% -68.81% (p=0.008 n=5+5)
String 1.97ns ± 1% 0.70ns ± 1% -64.25% (p=0.008 n=5+5)
Bytes 8.90ns ± 2% 0.89ns ± 1% -89.95% (p=0.008 n=5+5)
NamedBytes 8.89ns ± 1% 8.88ns ± 1% ~ (p=0.548 n=5+5)
BytesArray 10.0ns ± 2% 10.2ns ± 1% +1.58% (p=0.048 n=5+5)
SliceLen 1.97ns ± 1% 0.45ns ± 1% -77.22% (p=0.008 n=5+5)
MapLen 2.62ns ± 1% 3.07ns ± 1% +17.24% (p=0.008 n=5+5)
StringLen 1.96ns ± 1% 1.98ns ± 2% ~ (p=0.151 n=5+5)
ArrayLen 1.96ns ± 1% 2.19ns ± 1% +11.46% (p=0.008 n=5+5)
SliceCap 1.76ns ± 1% 0.45ns ± 2% -74.28% (p=0.008 n=5+5)
There's a slight slowdown (~10-20%) for obtaining the length
of a string or map, but a substantial improvement for slices.
Performance according to encoding/json:
CodeMarshal 555µs ± 2% 562µs ± 4% ~ (p=0.421 n=5+5)
MarshalBytes/32 163ns ± 1% 157ns ± 1% -3.82% (p=0.008 n=5+5)
MarshalBytes/256 453ns ± 1% 447ns ± 1% ~ (p=0.056 n=5+5)
MarshalBytes/4096 4.10µs ± 1% 4.09µs ± 0% ~ (p=1.000 n=5+4)
CodeUnmarshal 3.16ms ± 2% 3.02ms ± 1% -4.18% (p=0.008 n=5+5)
CodeUnmarshalReuse 2.64ms ± 3% 2.51ms ± 2% -4.81% (p=0.016 n=5+5)
UnmarshalString 65.4ns ± 4% 64.1ns ± 0% ~ (p=0.190 n=5+4)
UnmarshalFloat64 59.8ns ± 5% 58.9ns ± 2% ~ (p=0.222 n=5+5)
UnmarshalInt64 51.7ns ± 1% 50.0ns ± 2% -3.26% (p=0.008 n=5+5)
EncodeMarshaler 23.6ns ±11% 20.8ns ± 1% -12.10% (p=0.016 n=5+4)
Add all inlineable methods of Value to cmd/compile/internal/test/inl_test.go.
Change-Id: Ifc192491918af6b62f7fe3a094a5a5256bfb326d
Reviewed-on: https://go-review.googlesource.com/c/go/+/400676
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2022-04-16 19:01:48 -07:00
|
|
|
"Value.OverflowComplex",
|
|
|
|
|
"Value.OverflowFloat",
|
|
|
|
|
"Value.OverflowInt",
|
|
|
|
|
"Value.OverflowUint",
|
|
|
|
|
"Value.String",
|
|
|
|
|
"Value.Type",
|
|
|
|
|
"Value.Uint",
|
|
|
|
|
"Value.UnsafeAddr",
|
2019-03-09 17:48:23 +00:00
|
|
|
"Value.pointer",
|
2017-09-28 20:44:21 +01:00
|
|
|
"add",
|
|
|
|
|
"align",
|
2019-03-09 18:09:10 +00:00
|
|
|
"flag.mustBe",
|
|
|
|
|
"flag.mustBeAssignable",
|
|
|
|
|
"flag.mustBeExported",
|
2017-09-28 20:44:21 +01:00
|
|
|
"flag.kind",
|
|
|
|
|
"flag.ro",
|
|
|
|
|
},
|
2017-09-22 15:15:23 -05:00
|
|
|
"regexp": {
|
|
|
|
|
"(*bitState).push",
|
|
|
|
|
},
|
2018-03-06 09:07:34 +03:00
|
|
|
"math/big": {
|
|
|
|
|
"bigEndianWord",
|
2019-03-04 16:48:28 -08:00
|
|
|
// The following functions require the math_big_pure_go build tag.
|
|
|
|
|
"addVW",
|
|
|
|
|
"subVW",
|
2018-03-06 09:07:34 +03:00
|
|
|
},
|
2019-08-24 08:59:01 +09:00
|
|
|
"math/rand": {
|
|
|
|
|
"(*rngSource).Int63",
|
|
|
|
|
"(*rngSource).Uint64",
|
|
|
|
|
},
|
2021-02-11 10:49:55 -08:00
|
|
|
"net": {
|
|
|
|
|
"(*UDPConn).ReadFromUDP",
|
|
|
|
|
},
|
cmd/compile: allow more inlining of functions that construct closures
[This is a roll-forward of CL 479095, which was reverted due to a bad
interaction between inlining and escape analysis since fixed in CL 482355.]
Currently, when the inliner is determining if a function is
inlineable, it descends into the bodies of closures constructed by
that function. This has several unfortunate consequences:
- If the closure contains a disallowed operation (e.g., a defer), then
the outer function can't be inlined. It makes sense that the
*closure* can't be inlined in this case, but it doesn't make sense
to punish the function that constructs the closure.
- The hairiness of the closure counts against the inlining budget of
the outer function. Since we currently copy the closure body when
inlining the outer function, this makes sense from the perspective
of export data size and binary size, but ultimately doesn't make
much sense from the perspective of what should be inlineable.
- Since the inliner walks into every closure created by an outer
function in addition to starting a walk at every closure, this adds
an n^2 factor to inlinability analysis.
This CL simply drops this behavior.
In std, this makes 57 more functions inlinable, and disallows inlining
for 10 (due to the basic instability of our bottom-up inlining
approach), for an net increase of 47 inlinable functions (+0.6%).
This will help significantly with the performance of the functions to
be added for #56102, which have a somewhat complicated nesting of
closures with a performance-critical fast path.
The downside of this seems to be a potential increase in export data
and text size, but the practical impact of this seems to be
negligible:
│ before │ after │
│ bytes │ bytes vs base │
Go/binary 15.12Mi ± 0% 15.14Mi ± 0% +0.16% (n=1)
Go/text 5.220Mi ± 0% 5.237Mi ± 0% +0.32% (n=1)
Compile/binary 22.92Mi ± 0% 22.94Mi ± 0% +0.07% (n=1)
Compile/text 8.428Mi ± 0% 8.435Mi ± 0% +0.08% (n=1)
Updates #56102.
Change-Id: I1f4fc96c71609c8feb59fecdb92b69ba7e3b5b41
Reviewed-on: https://go-review.googlesource.com/c/go/+/482356
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
2023-04-04 18:31:46 -04:00
|
|
|
"sync": {
|
|
|
|
|
// Both OnceFunc and its returned closure need to be inlinable so
|
|
|
|
|
// that the returned closure can be inlined into the caller of OnceFunc.
|
|
|
|
|
"OnceFunc",
|
|
|
|
|
"OnceFunc.func2", // The returned closure.
|
|
|
|
|
// TODO(austin): It would be good to check OnceValue and OnceValues,
|
|
|
|
|
// too, but currently they aren't reported because they have type
|
|
|
|
|
// parameters and aren't instantiated in sync.
|
|
|
|
|
},
|
2022-01-26 16:56:00 -05:00
|
|
|
"sync/atomic": {
|
|
|
|
|
// (*Bool).CompareAndSwap handled below.
|
|
|
|
|
"(*Bool).Load",
|
|
|
|
|
"(*Bool).Store",
|
|
|
|
|
"(*Bool).Swap",
|
|
|
|
|
"(*Int32).Add",
|
|
|
|
|
"(*Int32).CompareAndSwap",
|
|
|
|
|
"(*Int32).Load",
|
|
|
|
|
"(*Int32).Store",
|
|
|
|
|
"(*Int32).Swap",
|
|
|
|
|
"(*Int64).Add",
|
|
|
|
|
"(*Int64).CompareAndSwap",
|
|
|
|
|
"(*Int64).Load",
|
|
|
|
|
"(*Int64).Store",
|
|
|
|
|
"(*Int64).Swap",
|
|
|
|
|
"(*Uint32).Add",
|
|
|
|
|
"(*Uint32).CompareAndSwap",
|
|
|
|
|
"(*Uint32).Load",
|
|
|
|
|
"(*Uint32).Store",
|
|
|
|
|
"(*Uint32).Swap",
|
|
|
|
|
"(*Uint64).Add",
|
|
|
|
|
"(*Uint64).CompareAndSwap",
|
|
|
|
|
"(*Uint64).Load",
|
|
|
|
|
"(*Uint64).Store",
|
|
|
|
|
"(*Uint64).Swap",
|
|
|
|
|
"(*Uintptr).Add",
|
|
|
|
|
"(*Uintptr).CompareAndSwap",
|
|
|
|
|
"(*Uintptr).Load",
|
|
|
|
|
"(*Uintptr).Store",
|
|
|
|
|
"(*Uintptr).Swap",
|
2023-02-01 02:04:29 +07:00
|
|
|
"(*Pointer[go.shape.int]).CompareAndSwap",
|
|
|
|
|
"(*Pointer[go.shape.int]).Load",
|
|
|
|
|
"(*Pointer[go.shape.int]).Store",
|
|
|
|
|
"(*Pointer[go.shape.int]).Swap",
|
2022-01-26 16:56:00 -05:00
|
|
|
},
|
2017-09-13 15:04:16 +02:00
|
|
|
}
|
|
|
|
|
|
2021-11-25 14:20:39 +08:00
|
|
|
if runtime.GOARCH != "386" && runtime.GOARCH != "loong64" && runtime.GOARCH != "mips64" && runtime.GOARCH != "mips64le" && runtime.GOARCH != "riscv64" {
|
2022-10-05 15:29:29 +08:00
|
|
|
// nextFreeFast calls sys.TrailingZeros64, which on 386 is implemented in asm and is not inlinable.
|
2017-09-20 13:09:08 -05:00
|
|
|
// We currently don't have midstack inlining so nextFreeFast is also not inlinable on 386.
|
2022-10-05 15:29:29 +08:00
|
|
|
// On loong64, mips64x and riscv64, TrailingZeros64 is not intrinsified and causes nextFreeFast
|
|
|
|
|
// too expensive to inline (Issue 22239).
|
2017-09-20 13:09:08 -05:00
|
|
|
want["runtime"] = append(want["runtime"], "nextFreeFast")
|
2022-04-29 13:21:44 -07:00
|
|
|
// Same behavior for heapBits.nextFast.
|
|
|
|
|
want["runtime"] = append(want["runtime"], "heapBits.nextFast")
|
2017-10-20 10:53:48 -04:00
|
|
|
}
|
|
|
|
|
if runtime.GOARCH != "386" {
|
2022-10-05 15:29:29 +08:00
|
|
|
// As explained above, TrailingZeros64 and TrailingZeros32 are not Go code on 386.
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
// The same applies to Bswap32.
|
2022-10-05 15:29:29 +08:00
|
|
|
want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "TrailingZeros64")
|
|
|
|
|
want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "TrailingZeros32")
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
want["runtime/internal/sys"] = append(want["runtime/internal/sys"], "Bswap32")
|
|
|
|
|
}
|
2019-03-09 17:48:23 +00:00
|
|
|
if bits.UintSize == 64 {
|
2021-04-08 16:08:55 +08:00
|
|
|
// mix is only defined on 64-bit architectures
|
|
|
|
|
want["runtime"] = append(want["runtime"], "mix")
|
2022-01-26 16:56:00 -05:00
|
|
|
// (*Bool).CompareAndSwap is just over budget on 32-bit systems (386, arm).
|
|
|
|
|
want["sync/atomic"] = append(want["sync/atomic"], "(*Bool).CompareAndSwap")
|
2017-09-20 13:09:08 -05:00
|
|
|
}
|
|
|
|
|
|
2019-03-09 17:48:23 +00:00
|
|
|
switch runtime.GOARCH {
|
2020-04-14 02:36:36 +10:00
|
|
|
case "386", "wasm", "arm":
|
2019-03-09 17:48:23 +00:00
|
|
|
default:
|
|
|
|
|
// TODO(mvdan): As explained in /test/inline_sync.go, some
|
|
|
|
|
// architectures don't have atomic intrinsics, so these go over
|
|
|
|
|
// the inlining budget. Move back to the main table once that
|
|
|
|
|
// problem is solved.
|
|
|
|
|
want["sync"] = []string{
|
|
|
|
|
"(*Mutex).Lock",
|
|
|
|
|
"(*Mutex).Unlock",
|
|
|
|
|
"(*RWMutex).RLock",
|
|
|
|
|
"(*RWMutex).RUnlock",
|
|
|
|
|
"(*Once).Do",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-17 14:08:03 -05:00
|
|
|
// Functions that must actually be inlined; they must have actual callers.
|
|
|
|
|
must := map[string]bool{
|
|
|
|
|
"compress/flate.byLiteral.Len": true,
|
|
|
|
|
"compress/flate.byLiteral.Less": true,
|
|
|
|
|
"compress/flate.byLiteral.Swap": true,
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-14 15:51:18 +01:00
|
|
|
notInlinedReason := make(map[string]string)
|
2017-09-13 21:03:20 +02:00
|
|
|
pkgs := make([]string, 0, len(want))
|
|
|
|
|
for pname, fnames := range want {
|
|
|
|
|
pkgs = append(pkgs, pname)
|
|
|
|
|
for _, fname := range fnames {
|
cmd/compile: add more runtime funcs to inline test
This is based from a list that Keith Randall provided in mid-2016. These
are all funcs that, at the time, were important and small enough that
they should be clearly inlined.
The runtime has changed a bit since then. Ctz16 and Ctz8 were removed,
so don't add them. stringtoslicebytetmp was moved to the backend, so
it's no longer a Go function. And itabhash was moved to itabHashFunc.
The only other outlier is adjustctxt, which is not inlineable at the
moment. I've added a TODO and will address it myself in a separate
commit.
While at it, error if any funcs in the input table are duplicated.
They're never useful and typos could lead to unintentionally thinking a
function is inlineable when it actually isn't.
And, since the lists are getting long, start sorting alphabetically.
Finally, rotl_31 is only defined on 64-bit architectures, and the added
runtime/internal/sys funcs are assembly on 386 and thus non-inlineable
in that case.
Updates #21851.
Change-Id: Ib99ab53d777860270e8fd4aefc41adb448f13662
Reviewed-on: https://go-review.googlesource.com/65351
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
2017-09-22 12:21:36 +01:00
|
|
|
fullName := pname + "." + fname
|
|
|
|
|
if _, ok := notInlinedReason[fullName]; ok {
|
|
|
|
|
t.Errorf("duplicate func: %s", fullName)
|
|
|
|
|
}
|
|
|
|
|
notInlinedReason[fullName] = "unknown reason"
|
2017-09-13 21:03:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-18 12:50:49 -04:00
|
|
|
args := append([]string{"build", "-gcflags=-m -m", "-tags=math_big_pure_go"}, pkgs...)
|
2022-11-15 09:57:01 -05:00
|
|
|
cmd := testenv.CleanCmdEnv(testenv.Command(t, testenv.GoToolPath(t), args...))
|
2017-09-14 15:51:18 +01:00
|
|
|
pr, pw := io.Pipe()
|
|
|
|
|
cmd.Stdout = pw
|
|
|
|
|
cmd.Stderr = pw
|
|
|
|
|
cmdErr := make(chan error, 1)
|
|
|
|
|
go func() {
|
|
|
|
|
cmdErr <- cmd.Run()
|
|
|
|
|
pw.Close()
|
|
|
|
|
}()
|
|
|
|
|
scanner := bufio.NewScanner(pr)
|
2017-09-13 21:03:20 +02:00
|
|
|
curPkg := ""
|
2017-09-14 15:51:18 +01:00
|
|
|
canInline := regexp.MustCompile(`: can inline ([^ ]*)`)
|
2018-09-17 14:08:03 -05:00
|
|
|
haveInlined := regexp.MustCompile(`: inlining call to ([^ ]*)`)
|
2017-09-14 15:51:18 +01:00
|
|
|
cannotInline := regexp.MustCompile(`: cannot inline ([^ ]*): (.*)`)
|
|
|
|
|
for scanner.Scan() {
|
|
|
|
|
line := scanner.Text()
|
|
|
|
|
if strings.HasPrefix(line, "# ") {
|
|
|
|
|
curPkg = line[2:]
|
|
|
|
|
continue
|
|
|
|
|
}
|
2018-09-17 14:08:03 -05:00
|
|
|
if m := haveInlined.FindStringSubmatch(line); m != nil {
|
2017-09-14 15:51:18 +01:00
|
|
|
fname := m[1]
|
|
|
|
|
delete(notInlinedReason, curPkg+"."+fname)
|
|
|
|
|
continue
|
2017-09-13 21:03:20 +02:00
|
|
|
}
|
2018-09-17 14:08:03 -05:00
|
|
|
if m := canInline.FindStringSubmatch(line); m != nil {
|
|
|
|
|
fname := m[1]
|
|
|
|
|
fullname := curPkg + "." + fname
|
2019-02-22 15:53:52 +00:00
|
|
|
// If function must be inlined somewhere, being inlinable is not enough
|
2018-09-17 14:08:03 -05:00
|
|
|
if _, ok := must[fullname]; !ok {
|
|
|
|
|
delete(notInlinedReason, fullname)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-14 15:51:18 +01:00
|
|
|
if m := cannotInline.FindStringSubmatch(line); m != nil {
|
|
|
|
|
fname, reason := m[1], m[2]
|
|
|
|
|
fullName := curPkg + "." + fname
|
|
|
|
|
if _, ok := notInlinedReason[fullName]; ok {
|
|
|
|
|
// cmd/compile gave us a reason why
|
|
|
|
|
notInlinedReason[fullName] = reason
|
|
|
|
|
}
|
2017-09-13 15:04:16 +02:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-14 15:51:18 +01:00
|
|
|
if err := <-cmdErr; err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
for fullName, reason := range notInlinedReason {
|
|
|
|
|
t.Errorf("%s was not inlined: %s", fullName, reason)
|
2017-09-13 15:04:16 +02:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-10 13:39:30 -04:00
|
|
|
|
|
|
|
|
func collectInlCands(msgs string) map[string]struct{} {
|
|
|
|
|
rv := make(map[string]struct{})
|
|
|
|
|
lines := strings.Split(msgs, "\n")
|
|
|
|
|
re := regexp.MustCompile(`^\S+\s+can\s+inline\s+(\S+)`)
|
|
|
|
|
for _, line := range lines {
|
|
|
|
|
m := re.FindStringSubmatch(line)
|
|
|
|
|
if m != nil {
|
|
|
|
|
rv[m[1]] = struct{}{}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return rv
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestIssue56044(t *testing.T) {
|
|
|
|
|
if testing.Short() {
|
|
|
|
|
t.Skipf("skipping test: too long for short mode")
|
|
|
|
|
}
|
|
|
|
|
if !goexperiment.CoverageRedesign {
|
|
|
|
|
t.Skipf("skipping new coverage tests (experiment not enabled)")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testenv.MustHaveGoBuild(t)
|
|
|
|
|
|
|
|
|
|
modes := []string{"-covermode=set", "-covermode=atomic"}
|
|
|
|
|
|
|
|
|
|
for _, mode := range modes {
|
|
|
|
|
// Build the Go runtime with "-m", capturing output.
|
|
|
|
|
args := []string{"build", "-gcflags=runtime=-m", "runtime"}
|
2022-11-15 09:57:01 -05:00
|
|
|
cmd := testenv.Command(t, testenv.GoToolPath(t), args...)
|
2022-10-10 13:39:30 -04:00
|
|
|
b, err := cmd.CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("build failed (%v): %s", err, b)
|
|
|
|
|
}
|
|
|
|
|
mbase := collectInlCands(string(b))
|
|
|
|
|
|
|
|
|
|
// Redo the build with -cover, also with "-m".
|
|
|
|
|
args = []string{"build", "-gcflags=runtime=-m", mode, "runtime"}
|
2022-11-15 09:57:01 -05:00
|
|
|
cmd = testenv.Command(t, testenv.GoToolPath(t), args...)
|
2022-10-10 13:39:30 -04:00
|
|
|
b, err = cmd.CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatalf("build failed (%v): %s", err, b)
|
|
|
|
|
}
|
|
|
|
|
mcov := collectInlCands(string(b))
|
|
|
|
|
|
|
|
|
|
// Make sure that there aren't any functions that are marked
|
|
|
|
|
// as inline candidates at base but not with coverage.
|
|
|
|
|
for k := range mbase {
|
|
|
|
|
if _, ok := mcov[k]; !ok {
|
|
|
|
|
t.Errorf("error: did not find %s in coverage -m output", k)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|