type T [3]string
Prior to this change, we generated this equality alg for T:
func eqT(p, q *T) (r bool) {
for i := range *p {
if len(p[i]) == len(q[i]) {
} else {
return
}
}
for j := range *p {
if runtime.memeq(p[j].ptr, q[j].ptr, len(p[j])) {
} else {
return
}
}
return true
}
That first loop can be profitably eliminated;
it's cheaper to spell out 3 length equality checks.
We now generate:
func eqT(p, q *T) (r bool) {
if len(p[0]) == len(q[0]) &&
len(p[1]) == len(q[1]) &&
len(p[2]) == len(q[2]) {
} else {
return
}
for i := 0; i < len(p); i++ {
if runtime.memeq(p[j].ptr, q[j].ptr, len(p[j])) {
} else {
return
}
}
return true
}
We now also eliminate loops for small float arrays as well,
and for any array of size 1.
These cutoffs were selected to minimize code size on amd64
at this moment, for lack of a more compelling methodology.
Any smallish number would do.
The switch from range loops to plain for loops allowed me
to use a temp instead of a named var, which eliminated
a pointless argument to checkAll.
The code to construct them is also a bit clearer, in my opinion.
Change-Id: I1bdd8ee4a2739d00806e66b17a4e76b46e71231a
Reviewed-on: https://go-review.googlesource.com/c/go/+/230210
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
type T [8]string
Prior to this change, we generated this equality algorithm for T:
func eqT(p, q *T) (r bool) {
for i := range *p {
if p[i] == q[i] {
} else {
return
}
}
return true
}
This change splits this into two loops, so that we can do the
cheap (length) half early and only then do the expensive (contents) half.
We now generate:
func eqT(p, q *T) (r bool) {
for i := range *p {
if len(p[i]) == len(q[i]) {
} else {
return
}
}
for j := range *p {
if runtime.memeq(p[j].ptr, q[j].ptr, len(p[j])) {
} else {
return
}
}
return true
}
The generated code is typically ~17% larger because it contains
two loops instead of one. In the future, we might want to unroll
the first loop when the array is small.
Change-Id: I26b2793b90ec6aff21766a411b15a4ff1096c03f
Reviewed-on: https://go-review.googlesource.com/c/go/+/230209
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
type T [8]interface{}
Prior to this change, we generated this equality algorithm for T:
func eqT(p, q *T) bool {
for i := range *p {
if p[i] != q[i] {
return false
}
}
return true
}
This change splits this into two loops, so that we can do the
cheap (type) half early and only then do the expensive (data) half.
We now generate:
func eqT(p, q *T) (r bool) {
for i := range *p {
if p[i].type == q[i].type {
} else {
return
}
}
for j := range *p {
if runtime.efaceeq(p[j].type, p[j].data, q[j].data) {
} else {
return
}
}
return true
}
The use of a named return value and a bare return is to work
around some typechecking problems that stymied me.
The structure of using equals and else (instead of not equals and then)
was for implementation convenience and clarity. As a bonus,
it generates slightly shorter code on AMD64, because zeroing a register
to return is cheaper than writing $1 to it.
The generated code is typically ~17% larger because it contains
two loops instead of one. In the future, we might want to unroll
the first loop when the array is small.
Change-Id: I5b2c8dd3384852f085c4f3e1f6ad20bc5ae59062
Reviewed-on: https://go-review.googlesource.com/c/go/+/230208
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
type T struct {
s interface{}
i int
}
Prior to this change, we generated this equality algorithm for T:
func eqT(p, q *T) bool {
return p.s.type == q.s.type &&
runtime.efaceeq(p.s.type, p.s.data, q.s.data) &&
p.i == q.i
}
This change splits the two halves of the interface equality,
so that we can do the cheap (type) half early and the expensive
(data) half late. We now generate:
func eqT(p, q *T) bool {
return p.s.type == q.s.type &&
p.i == q.i &&
runtime.efaceeq(p.s.type, p.s.data, q.s.data)
}
The generated code tends to be a bit smaller. Examples:
go/ast
.eq."".ForStmt 306 -> 304 (-0.65%)
.eq."".TypeAssertExpr 221 -> 219 (-0.90%)
.eq."".TypeSwitchStmt 228 -> 226 (-0.88%)
.eq."".ParenExpr 150 -> 148 (-1.33%)
.eq."".IndexExpr 221 -> 219 (-0.90%)
.eq."".SwitchStmt 228 -> 226 (-0.88%)
.eq."".RangeStmt 334 -> 332 (-0.60%)
Change-Id: Iec9e24f214ca772416202b9fb9252e625c22380e
Reviewed-on: https://go-review.googlesource.com/c/go/+/230207
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Refactor out creating the two Nodes needed to check interface equality.
Preliminary work to other optimizations.
Passes toolstash-check.
Change-Id: Id6b39e8e78f07289193423d0ef905d70826acf89
Reviewed-on: https://go-review.googlesource.com/c/go/+/230206
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
type T struct {
s string
i int
}
Prior to this change, we generated this equality algorithm for T:
func eqT(p, q *T) bool {
return len(p.s) == len(q.s) &&
runtime.memequal(p.s.ptr, q.s.ptr, len(p.s)) &&
p.i == q.i
}
This change splits the two halves of the string equality,
so that we can do the cheap (length) half early and the expensive
(contents) half late. We now generate:
func eqT(p, q *T) bool {
return len(p.s) == len(q.s) &&
p.i == q.i &&
runtime.memequal(p.s.ptr, q.s.ptr, len(p.s))
}
The generated code for these functions tends to be a bit shorter. Examples:
runtime
.eq."".Frame 274 -> 272 (-0.73%)
.eq."".funcinl 249 -> 247 (-0.80%)
.eq."".modulehash 207 -> 205 (-0.97%)
Change-Id: I4efac9f7d410f0a11a94dcee2bf9c0b49b60e301
Reviewed-on: https://go-review.googlesource.com/c/go/+/230205
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Refactor out creating the two Nodes needed to check string equality.
Preliminary work to other optimizations.
Passes toolstash-check.
Change-Id: I72e824dac904e579b8ba9a3669a94fa1471112d2
Reviewed-on: https://go-review.googlesource.com/c/go/+/230204
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
We only generate if statements via CondBreak, which is nice as the
control flow is simple and easy to work with. It seems like the If type
was added but never used, so remove it to avoid confusion.
We had a TODO about replacing CondBreak with If instead. I gave that a
try, but it doesn't seem worth the effort. The code gets more complex
and we don't really win anything in return.
While at it, don't use op strings as format strings in exprf. This
doesn't cause any issue at the moment, but it's best to be explicit
about the operator not containing any formatting verbs.
Change-Id: Ib59ad72d3628bf91594efc609e222232ad1e8748
Reviewed-on: https://go-review.googlesource.com/c/go/+/230257
Reviewed-by: Keith Randall <khr@golang.org>
Apply strong aux typing to lowering rules that do not require
modification beyond substituting -> for =>. Other lowering rules
and all the optimization rules will follow. I'm breaking it up
to allow toolstash-check to pass on the big CLs.
Passes toolstash-check -all.
Change-Id: I6f1340058a8eb5a1390411e59fcbea9d7f777e58
Reviewed-on: https://go-review.googlesource.com/c/go/+/229400
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Convert some Move and Zero Lowering rules to strongly-typed versions.
Passes toolstash-check.
Change-Id: Icaabe05e206d59798e5883a90e9a33bb30270b13
Reviewed-on: https://go-review.googlesource.com/c/go/+/229919
Reviewed-by: Michael Munday <mike.munday@ibm.com>
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The commuteDepth variable is no longer necessary; remove it.
Else branches after a log.Fatal call are unnecessary.
Also make the unbalanced return an integer, so we can differentiate
positive from negative cases. We only want to continue a rule with the
following lines if this balance is positive, for example.
While at it, make the balance loop stop when it goes negative, to not
let ")(" seem balanced.
Change-Id: I8aa313343ca5a2f07f638b62a0398fdf108fc9eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/228822
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Ensures that a canceled client request for Switching Protocols
(e.g. h2c, Websockets) will cause the underlying connection to
be terminated.
Adds a goroutine in handleUpgradeResponse in order to select on
the incoming client request's context and appropriately cancel it.
Fixes#35559
Change-Id: I1238e18fd4cce457f034f78d9cdce0e7f93b8bf6
GitHub-Last-Rev: 3629c78493
GitHub-Pull-Request: golang/go#38021
Reviewed-on: https://go-review.googlesource.com/c/go/+/224897
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Everywhere else is using "cancellation"
The reasoning is mentioned in 170060
> Though there is variation in the spelling of canceled,
> cancellation is always spelled with a double l.
>
> Reference: https://www.grammarly.com/blog/canceled-vs-cancelled/
Change-Id: Ifc97c6785afb401814af77c377c2e2745ce53c5a
GitHub-Last-Rev: 05edd7477d
GitHub-Pull-Request: golang/go#38662
Reviewed-on: https://go-review.googlesource.com/c/go/+/230200
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
For GOOS=windows the path separator characters '\' and ':' also need be
replaced.
Updates #38465
Change-Id: If7c8cf93058c87d7df6cda140e82fd76578fe699
Reviewed-on: https://go-review.googlesource.com/c/go/+/229837
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
If an I/O operation fails because a deadline was exceeded,
return os.ErrDeadlineExceeded. We used to return poll.ErrTimeout,
an internal error, and told users to check the Timeout method.
However, there are other errors with a Timeout method that returns true,
notably syscall.ETIMEDOUT which is returned for a keep-alive timeout.
Checking errors.Is(err, os.ErrDeadlineExceeded) should permit code
to reliably tell why it failed.
This change does not affect the handling of net.Dialer.Deadline,
nor does it change the handling of net.DialContext when the context
deadline is exceeded. Those cases continue to return an error
reported as "i/o timeout" for which Timeout is true, but that error
is not os.ErrDeadlineExceeded.
Fixes#31449
Change-Id: I0323f42e944324c6f2578f00c3ac90c24fe81177
Reviewed-on: https://go-review.googlesource.com/c/go/+/228645
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
This triggers in 131 functions in std+cmd.
In those functions, it often helps considerably
(2-10% text size reduction).
Noticed while working on #38554.
Change-Id: Id0dbb8e7cb21d469ec08ec3d5be9beb9e8291e9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/229707
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
We set up static symbols during walk that
we later make copies of to initialize local variables.
It is difficult to ascertain at that time exactly
when copying a symbol is profitable vs locally
initializing an autotmp.
During SSA, we are much better placed to optimize.
This change recognizes when we are copying from a
global readonly all-zero symbol and replaces it with
direct zeroing.
This often allows the all-zero symbol to be
deadcode eliminated at link time.
This is not ideal--it makes for large object files,
and longer link times--but it is the cleanest fix I could find.
This makes the final binary for the program in #38554
shrink from >500mb to ~2.2mb.
It also shrinks the standard binaries:
file before after Δ %
addr2line 4412496 4404304 -8192 -0.186%
buildid 2893816 2889720 -4096 -0.142%
cgo 4841048 4832856 -8192 -0.169%
compile 19926480 19922432 -4048 -0.020%
cover 5281816 5277720 -4096 -0.078%
link 6734648 6730552 -4096 -0.061%
nm 4366240 4358048 -8192 -0.188%
objdump 4755968 4747776 -8192 -0.172%
pprof 14653060 14612100 -40960 -0.280%
trace 11805940 11777268 -28672 -0.243%
vet 7185560 7181416 -4144 -0.058%
total 113588440 113465560 -122880 -0.108%
And not just by removing unnecessary symbols;
the program text shrinks a bit as well.
Fixes#38554
Change-Id: I8381ae6084ae145a5e0cd9410c451e52c0dc51c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/229704
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
Package amd64 is a more natural home for it.
It also makes it easier to see how many bytes
are being copied in ssa.html.
Passes toolstash-check.
Change-Id: I5ecf0f0f18e8db2faa2caf7a05028c310952bd94
Reviewed-on: https://go-review.googlesource.com/c/go/+/229703
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Since we're sleeping rather than waiting for the goroutines,
let the goroutines run forever.
Fixes#38595
Change-Id: I4cd611fd7565f6e8d91e50c9273d91c514825314
Reviewed-on: https://go-review.googlesource.com/c/go/+/229484
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
net/http/pprof: delta profile support
runtime/pprof: profile labels plumbing for goroutine profiles
Change-Id: I92e750dc894c8c6b3c3ba10f7be58bb541d3c289
Reviewed-on: https://go-review.googlesource.com/c/go/+/230023
Reviewed-by: Ian Lance Taylor <iant@golang.org>
These comparisons are fairly arbitrary,
but they should be more stable in the face
of other compiler changes than value ID.
This reduces the number of value ID
comparisons in schedule while running
make.bash from 542,442 to 99,703.
There are lots of changes to generated code
from this change, but they appear to
be overall neutral.
It is possible to further reduce the
number of comparisons in schedule;
I have changes locally that reduce the
number to about 25,000 during make.bash.
However, the changes are increasingly
complex and arcane, and reduce in much less
code churn. Given that the goal is stability,
that suggests that this is a reasonable
place to stop, at least for now.
Change-Id: Ie3a75f84fd3f3fdb102fcd0b29299950ea66b827
Reviewed-on: https://go-review.googlesource.com/c/go/+/229799
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Falling back to comparing Value.ID during scheduling
is undesirable: Not only are we simply hoping for a good
outcome, but the decision we make will be easily perturbed
by other compiler changes, leading to random fluctuations.
This change adds another decision point to the scheduler
by scheduling Values with many uses earlier.
Values with fewer uses are less likely to be spilled for
other reasons, so we should issue them as late as possible
in the hope of avoiding a spill.
This reduces the number of Value ID comparisons
in schedule while running make.bash
from 1,000,844 to 542,442.
As you would expect, this changes a lot of functions,
but the overall trend is positive:
file before after Δ %
api 5237184 5233088 -4096 -0.078%
compile 19926480 19918288 -8192 -0.041%
cover 5281816 5277720 -4096 -0.078%
dist 3711608 3707512 -4096 -0.110%
total 113588440 113567960 -20480 -0.018%
Change-Id: Ic99ebc4c614d4ae3807ce44473ec6b04684388ec
Reviewed-on: https://go-review.googlesource.com/c/go/+/229798
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
The compiler produces high quality error messages when an interface is
implemented by *T, rather than T. This change improves the analogous
error messages in go/types, from "missing method X" to "missing method
X (X has pointer receiver)".
I am open to improving this message further - I didn't copy the compiler
error message exactly because, at one of the call sites of
(*check).missingMethod, we no longer have access to the name of the
interface.
Fixesgolang/go#36336
Change-Id: Ic4fc38b13fff9e5d9a69cc750c21e0b0c34d85a8
Reviewed-on: https://go-review.googlesource.com/c/go/+/229801
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Keep track of all expressions encountered while
generating a rewrite result, and re-use them whenever possible.
Named expressions may still be used for clarity when desired.
Change-Id: I640dca108763eb8baeff8f9a4169300af3445b82
Reviewed-on: https://go-review.googlesource.com/c/go/+/229800
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
This page has moved to the x/website repo in CL 229482 (commit
golang/website@70f4ee8c7e).
Remove the old copy in this repo since it's no longer used.
For #29206.
Change-Id: Ief093ed8c5dfec43e06d473e4282275f61da74a5
Reviewed-on: https://go-review.googlesource.com/c/go/+/229485
Reviewed-by: Alexander Rakoczy <alex@golang.org>