Using go/types to get rid of all unused variables in CL 189798 was a
neat idea, but it was pretty expensive. go/types is a full typechecker,
which does a lot more work than we actually need. Moreover, we had to
run it multiple times, to catch variables that became unused after
removing existing unused variables.
Instead, write our own little detector for unused imports and variables.
It doesn't use ast.Walk, as we need to know what fields we're
inspecting. For example, in "foo := bar", "foo" is declared, and "bar"
is used, yet they both appear as simple *ast.Ident cases under ast.Walk.
The code is documented to explain how unused variables are detected in a
single syntax tree pass. Since this happens after we've generated a
complete go/ast.File, we don't need to worry about our own simplified
node types.
The generated code is the same, but rulegen is much faster and uses less
memory at its peak, so it should scale better with time.
With 'benchcmd Rulegen go run *.go' on perflock, we get:
name old time/op new time/op delta
Rulegen 4.00s ± 0% 3.41s ± 1% -14.70% (p=0.008 n=5+5)
name old user-time/op new user-time/op delta
Rulegen 14.1s ± 1% 10.6s ± 1% -24.62% (p=0.008 n=5+5)
name old sys-time/op new sys-time/op delta
Rulegen 318ms ±26% 263ms ± 9% ~ (p=0.056 n=5+5)
name old peak-RSS-bytes new peak-RSS-bytes delta
Rulegen 231MB ± 4% 181MB ± 3% -21.69% (p=0.008 n=5+5)
Change-Id: I8387d52818f6131357868ad348dac8c96d926191
Reviewed-on: https://go-review.googlesource.com/c/go/+/191782
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
The listed invariant, while technically true, was misleading, and the
invariant can be tightened. We never actually get to (d.hi ==
d.overflow), due to the "d.hi--" line in the decoder.decode method.
This is a comment-only commit, changing the comment to match the code.
A follow-up commit could restore the comment, changing the code to match
the original intented invariant. But the first step is to have the
comment and the code say the same thing.
Change-Id: Ifc9f78d5060454fc107af9be298026bf3043d400
Reviewed-on: https://go-review.googlesource.com/c/go/+/191358
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
After CL 192979, it is safe now to optimize isfat slightly to handle
1-field structs and 1-element arrays.
Change-Id: Ie3bc30299abbcef36eee7a0681997cc2f88ed6a3
Reviewed-on: https://go-review.googlesource.com/c/go/+/192980
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
When reaching const declaration, Checker override context iota to use
correct iota value, but does not restore the old value when exit, and
always set context iota to nil. It ends up with undefined iota after
const declaration.
To fix it, preserve the original iota value and restore it after const
declaration.
Fixes#34228
Change-Id: I42d5efb55a57e5ddc369bb72d31f1f039c92361c
Reviewed-on: https://go-review.googlesource.com/c/go/+/194737
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Part of the general trend of moving yyerror calls out of walk and into
typecheck.
Notably, this requires splitting test/typeswitch2.go into two files,
because now some of the errors are reported during typecheck and
others are still reported during walk; and if there were any errors
during typecheck, then cmd/compile exits without invoking walk.
Passes toolstash-check.
Change-Id: I05ee0c00b99af659ee1eef098d342d0d736cf31e
Reviewed-on: https://go-review.googlesource.com/c/go/+/194659
Reviewed-by: Robert Griesemer <gri@golang.org>
While superficially type and expression switch handling seem similar
and that it would be worthwhile to unify typechecking them, it turns
out they're actually different enough that separately handling them is
fewer lines of code and easier to understand as well.
Passes toolstash-check.
Change-Id: I357d6912dd580639b6001bccdb2e227ed83c6fe9
Reviewed-on: https://go-review.googlesource.com/c/go/+/194566
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
The go/ast package uses and guarantees nil slices for optional
elements that weren't present in the parsed source code, such as the
list of return values of a function. Packages using go/ast rely on
this attribute and check for nils explicitly.
One such package is go/printer. In the presence of empty slices
instead of nil slices, it generates invalid code, such as "case :"
instead of "default:". The issues that this CL fixes are all
manifestations of that problem, each for a different syntactic
element.
Fixes#33103Fixes#33104Fixes#33105
Change-Id: I219f95a7da820eaf697a4ee227d458ab6e4a80bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/187917
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
'go get' accepts arguments of the form path@version, and it passes
them through search.CleanPatterns before querying proxies. With this
change, CleanPatterns preserves text after '@' and will strip trailing
slashes from the patn.
Previously, we did not strip trailing slashes when a version was
present, which caused proxy base URL validation to fail. Module paths
that end with ".go" (for example, github.com/nats-io/nats.go) use
trailing slashes to prevent 'go build' and other commands from
interpreting packages as source file names, so this caused unnecessary
problems for them.
Updates #32483
Change-Id: Id3730c52089e52f1cac446617c20132a3021a808
Reviewed-on: https://go-review.googlesource.com/c/go/+/194600
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Since modules now support parsing multiple forms of versions (including
commit hash and source control tag), I think modconv.ConvertLegacyConfig
no longer needs modfetch.ImportRepoRev. So I suggest that we use modules
to convert legacy config instead of using VCS directly. By doing this,
we can make the module proxy participate in the conversion process and
benefit from it (such as speeding up "go mod init" or breaking through
the firewall).
And since modconv.ConvertLegacyConfig is the only caller of
modfetch.ImportRepoRev, I think modfetch.ImportRepoRev can be removed.
Fixes#33767
Change-Id: Ic79b14fa805ed297ca1735a8498cfed2a5ddeec2
Reviewed-on: https://go-review.googlesource.com/c/go/+/191218
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Some of the instructions were incorrectly grouped - untangle this and
separate the RV64I instructions, which are under separate sections of
the RISC-V specification.
Change-Id: I232962ab4054bf0b4745887506f51e74ea73f73d
Reviewed-on: https://go-review.googlesource.com/c/go/+/194238
Reviewed-by: Cherry Zhang <cherryyz@google.com>
The signature of parseMetaGoImports implies that it can return an error,
but it has not done so since CL 119675. Restore the missing error check,
and remove the named return-values to avoid reintroducing this bug in the
future.
Updates #30748
Updates #21291
Change-Id: Iab19ade5b1c23c282f3c385a55ed277465526515
Reviewed-on: https://go-review.googlesource.com/c/go/+/189778
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
The doc comment for charsetReader claims that it supports UTF-8,
but in practice it does not: instead, it is never invoked for UTF-8.
We could update the comment to clarify that fact, but it seems simpler
to change the implementation to match the comment.
Change-Id: I39b11395ccef3feff96480b9294e8f2a232728dd
Reviewed-on: https://go-review.googlesource.com/c/go/+/189777
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Incoming URLs may omit the scheme to indicate “either HTTP or HTTPS”.
For such URLs, log the scheme actually used instead of leaving it out.
(This issue was noticed while triaging #34075.)
Updates #34075
Change-Id: I39e5ca83543dd780258d41d5c2c4ba907cd20e5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/193262
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Currently, when running the "CC=clang go run -msan misc/cgo/
testsanitizers/testdata/msan.go" command on arm64, it will
report an error and the error is reported by llvm/compiler-rt/
lib/msan and it is "Make sure to compile with -fPIE and to link
with -pie".
This CL fixes this issue, using PIE link mode when using MSAN
on arm64.
This CL also updates the related document and go build help message.
Fixes#33712
Change-Id: I0cc9d95f3fa264d6c042c27a40ccbb82826922fb
Reviewed-on: https://go-review.googlesource.com/c/go/+/190482
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
If a go-import directive refers to a nonexistent repository, today we
treat that as an error fetching a module that actually exists.
That makes the HTTP server responsible for determining which
repositories do or do not exist, which may in general depend on
the user's separately-stored credentials, and imposes significant
complexity on such a server, which can otherwise be very simple.
Instead, check the repository URL and/or error message to try to
determine whether the repository exists at all. If the repo does not
exist, treat its absence as a “not found” error — as if the server had
not returned it in the first place.
Updates #34094
Change-Id: I142619ff43b96d0de428cdd0b01cca828c9ba234
Reviewed-on: https://go-review.googlesource.com/c/go/+/194561
Reviewed-by: Jay Conrod <jayconrod@google.com>
Since Go 1.2 every string can be marshaled to JSON without error even if it
contains invalid UTF-8 byte sequences. Therefore there is no need to use
Marshal again for the only reason of enclosing the string in double quotes.
Not using Marshal here also removes the error check as there has not been a
way for Marshal to fail anyway.
name old time/op new time/op delta
Issue34127-4 360ns ± 3% 200ns ± 3% -44.56% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
Issue34127-4 56.0B ± 0% 40.0B ± 0% -28.57% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
Issue34127-4 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.008 n=5+5)
Fixes#34154
Change-Id: Ib60dc11980f9b20d8bef2982de7168943d632263
GitHub-Last-Rev: 9b0ac1d4c5
GitHub-Pull-Request: golang/go#34127
Reviewed-on: https://go-review.googlesource.com/c/go/+/193604
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Added a new instruction, NOPH, with the encoding [0x0700](i.e: bcr 0, 0) and
replace the current 4-byte nop that was encoded using the WORD instruction.
This reduces the size of .text section in go binary by around 17KB and make
generated code easier to read.
Change-Id: I6a756df39e93c4415ea6d038ba4af001b8ccb286
Reviewed-on: https://go-review.googlesource.com/c/go/+/194344
Reviewed-by: Michael Munday <mike.munday@ibm.com>
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This allows the use of CLONE_VFORK and CLONE_VM for fork/exec, preventing
"fork/exec ...: cannot allocate memory" failures from occuring when attempting
to execute commands from a Go process that has a large memory footprint.
Additionally, this should reduce the latency of fork/exec on linux/arm64.
With CLONE_VM the child process shares the same memory with the parent
process. On its own this would lead to conflicting use of the same
memory, so CLONE_VFORK is used to suspend the parent process until the
child releases the memory when switching to the new program binary
via the exec syscall. When the parent process continues to run, one
has to consider the changes to memory that the child process did,
namely the return address of the syscall function needs to be restored
from a register.
exec.Command() callers can start in a faster manner, as child process who
do exec commands job can be cloned faster via vfork than via fork on arm64.
The same problem was addressed on linux/amd64 via issue #5838.
Updates #31936
Contributed by Howard Zhang <howard.zhang@arm.com> and Bin Lu <bin.lu@arm.com>
Change-Id: Ia99d81d877f564ec60d19f17e596276836576eaf
Reviewed-on: https://go-review.googlesource.com/c/go/+/189418
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
As discussed in #32912, a crash occurs when go runtime calls a VDSO function (say
__vdso_clock_gettime) and a signal arrives to that thread.
Since VDSO functions temporarily destroy the G register (R10),
Go functions asynchronously executed in that thread (i.e. Go's signal
handler) can try to load data from the destroyed G, which causes
segmentation fault.
To fix the issue a guard is inserted in front of sigtrampgo, so that the control escapes from
signal handlers without touching G in case the signal occurred in the VDSO context.
The test case included in the patch is take from discussion in a relevant thread on github:
https://github.com/golang/go/issues/32912#issuecomment-517874531.
This patch not only fixes the issue on AArch64 but also that on 32bit ARM.
Fixes#32912
Change-Id: I657472e54b7aa3c617fabc5019ce63aa4105624a
GitHub-Last-Rev: 28ce42c4a0
GitHub-Pull-Request: golang/go#34030
Reviewed-on: https://go-review.googlesource.com/c/go/+/192937
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Before this change, when DeepEqual checks values with cycle, it may
panic due to stack overflow.
Here is a sample to reproduce the issue.
makeCycleMap := func() interface{} {
cycleMap := map[string]interface{}{}
cycleMap["foo"] = cycleMap
return cycleMap
}
m1 := makeCycleMap()
m2 := makeCycleMap()
reflect.DeepEqual(m1, m2) // stack overflow
The root cause is that DeepEqual fails to cache interface values
in visited map, which is used to detect cycle. DeepEqual calls
CanAddr to check whether a value should be cached or not. However,
all values referenced by interface don't have flagAddr thus all these
values are not cached.
THe fix is to remove CanAddr calls and use underlying ptr in value
directly. As ptr is only read-only in DeepEqual for caching, it's
safe to do so. We don't use UnsafeAddr this time, because this method
panics when CanAddr returns false.
Fixes#33907
Change-Id: I2aa88cc060a2c2192b1d34c129c0aad4bd5597e7
Reviewed-on: https://go-review.googlesource.com/c/go/+/191940
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Make it clear that IsValid checks that we have valid
reflect.Value and not the value of `v`
fixes#34152
Change-Id: Ib3d359eeb3a82bf733b9ed17c777fc4c143bc29c
Reviewed-on: https://go-review.googlesource.com/c/go/+/193841
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This CL moves parameter tagging to before escape analysis is complete,
so we still have access to EscLocation. This will be useful once
EscLocation starts tracking higher-fidelity escape details.
Notably, this CL stops using n.Esc to record parameter escape analysis
details. Now escape analysis only ever sets n.Esc to EscNone or
EscHeap. (It still defaults to EscUnknown, and is set to EscNever in
some places though.)
Passes toolstash-check.
Updates #33981.
Change-Id: I50a91ea1e38c442092de6cd14e20b211f8f818c9
Reviewed-on: https://go-review.googlesource.com/c/go/+/193178
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Remove unnecessary conditional guard for a couple of assertions in the
type parser's update() method (inspired by comment from Robert). No
change in functionality.
Change-Id: I706a54569e75c6960768247889b7dec3f267dde9
Reviewed-on: https://go-review.googlesource.com/c/go/+/194565
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
If an embedded field refers to a type via a pointer, the parser needs
to know the name of the embedded field. It is possible that the
pointer type is not yet resolved. This CL fixes the parser to handle
that case by setting the pointer element type to the unresolved named
type while the pointer is being resolved.
Fixes#34182
Change-Id: I48435e0404362a85effd7463685c502290fa3c57
Reviewed-on: https://go-review.googlesource.com/c/go/+/194440
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
No behavior change; just inverting the loop ordering so the
per-parameter behavior is a bit clearer.
Passes toolstash-check.
Updates #33981.
Change-Id: I9bfcd7d0a4aff65a27ced157767ca2ba8038319a
Reviewed-on: https://go-review.googlesource.com/c/go/+/193177
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reset is already performed when retrieving from pool
Change-Id: Ia810dd18d3e55a1565a5ad435a00d1e46724576c
GitHub-Last-Rev: d9df74a4ae
GitHub-Pull-Request: golang/go#34195
Reviewed-on: https://go-review.googlesource.com/c/go/+/194338
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Also fix the key used to store the ID.
This is a significant speedup in cmd/go run time when using an
unreleased toolchain. For example, the TestGoBuildTestOnly cmd/go test
goes from 15 seconds to 1 second.
Change-Id: Ibfd697d55084db059c6b563f70f71f635e935391
Reviewed-on: https://go-review.googlesource.com/c/go/+/194441
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
This CL gets rid of the MOVDreg and MOVDnop SSA operations on
s390x. They were originally inserted to help avoid situations
where a sign/zero extension was elided but a spill invalidated
the optimization. It's not really clear we need to do this though
(amd64 doesn't have these ops for example) so long as we are
careful when removing sign/zero extensions. Also, the MOVDreg
technique doesn't work if the register is spilled before the
MOVDreg op (I haven't seen that in practice).
Removing these ops reduces the complexity of the rules and also
allows us to unblock optimizations. For example, the compiler can
now merge the loads in binary.{Big,Little}Endian.PutUint16 which
it wasn't able to do before. This CL reduces the size of the .text
section in the go tool by about 4.7KB (0.09%).
Change-Id: Icaddae7f2e4f9b2debb6fabae845adb3f73b41db
Reviewed-on: https://go-review.googlesource.com/c/go/+/173897
Run-TryBot: Michael Munday <mike.munday@ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This removes the unnecessary code to check whether the shift
is within limits or not when the shift amount is a constant.
The rules hit 23034 times when building std cmd.
grep -E "Wasm.rules:(106|107|121|122|139|140)" rulelog | wc -l
23034
Reduces the size of pkg/js_wasm by 132 bytes.
Change-Id: I64a2b8faca08c3b5039d6a027d4676130d2db18d
Reviewed-on: https://go-review.googlesource.com/c/go/+/194239
Run-TryBot: Agniva De Sarker <agniva.quicksilver@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Richard Musiol <neelance@gmail.com>
The indirect method checked the type of the child when indirecting a
pointer. If the current value is a pointer and we are decoding null, we
can skip this entirely and return early, avoiding the whole descent.
Fixes#31776
Change-Id: Ib8b2a2357572c41f56fceac59b5a858980f3f65e
Reviewed-on: https://go-review.googlesource.com/c/go/+/174699
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Leave reporting of multiple errors for strings alone for now;
we probably want to see all incorrect escape sequences in
runes/strings independent of other errors.
Fixes#33961.
Change-Id: Id722e95f802687963eec647d1d1841bd6ed17d35
Reviewed-on: https://go-review.googlesource.com/c/go/+/192499
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This code enables handling of ASN1's string type BMPString, used in some digital signatures.
Parsing code taken from golang.org/x/crypto/pkcs12.
Change-Id: Ibeae9cf4d8ae7c18f8b5420ad9244a16e117ff6b
GitHub-Last-Rev: 6945253514
GitHub-Pull-Request: golang/go#26690
Reviewed-on: https://go-review.googlesource.com/c/go/+/126624
Run-TryBot: Andrew Bonventre <andybons@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Bonventre <andybons@golang.org>
Rewording the comments for Join to do a better job of calling out
when Clean is called. Also clarifing other portions of the comment.
Fixes#29875
Change-Id: Ied43983bb10a97922898d28af133de0930224496
Reviewed-on: https://go-review.googlesource.com/c/go/+/194339
Reviewed-by: Rob Pike <r@golang.org>
Previously, we used a single "untyped number" type for all untyped
numeric constants. This led to vague error messages like "string(1.0)"
reporting that "1 (type untyped number)" can't be converted to string,
even though "string(1)" is valid.
This CL makes cmd/compile more like go/types by utilizing
types.Ideal{int,rune,float,complex} instead of types.Types[TIDEAL],
and keeping n.Type in sync with n.Val().Ctype() during constant
folding.
Thanks to K Heller for looking into this issue, and for the included
test case.
Fixes#21979.
Change-Id: Ibfea88c05704bc3c0a502a455d018a375589754d
Reviewed-on: https://go-review.googlesource.com/c/go/+/194019
Reviewed-by: Robert Griesemer <gri@golang.org>
This is a documentation-only change
Fixes#33298
Change-Id: I816058a872b57dc868dff11887214d9de92d9342
Reviewed-on: https://go-review.googlesource.com/c/go/+/188821
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
On modern 64bit CPUs a SHR, SHL or AND instruction take 1 cycle to execute.
A pair of shifts that operate on the same register will take 2 cycles
and needs to wait for the input register value to be available.
Large constants used to mask the high bits of a register with an AND
instruction can not be encoded as an immediate in the AND instruction
on amd64 and therefore need to be loaded into a register with a MOV
instruction.
However that MOV instruction is not dependent on the output register and
on many CPUs does not compete with the AND or shift instructions for
execution ports.
Using a pair of shifts to mask high bits instead of an AND to mask high
bits of a register has a shorter encoding and uses one less general
purpose register but is slower due to taking one clock cycle longer
if there is no register pressure that would make the AND variant need to
generate a spill.
For example the instructions emitted for (x & 1 << 63) before this CL are:
48c1ea3f SHRQ $0x3f, DX
48c1e23f SHLQ $0x3f, DX
after this CL the instructions are the same as GCC and LLVM use:
48b80000000000000080 MOVQ $0x8000000000000000, AX
4821d0 ANDQ DX, AX
Some platforms such as arm64 already have SSA optimization rules to fuse
two shift instructions back into an AND.
Removing the general rule to rewrite AND to SHR+SHL speeds up this benchmark:
var GlobalU uint
func BenchmarkAndHighBits(b *testing.B) {
x := uint(0)
for i := 0; i < b.N; i++ {
x &= 1 << 63
}
GlobalU = x
}
amd64/darwin on Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz:
name old time/op new time/op delta
AndHighBits-4 0.61ns ± 6% 0.42ns ± 6% -31.42% (p=0.000 n=25+25):
Updates #33826
Updates #32781
Change-Id: I862d3587446410c447b9a7265196b57f85358633
Reviewed-on: https://go-review.googlesource.com/c/go/+/191780
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Call the Nano methods of Timespec and Timeval in TimespecToNsec and
TimevalToNsec respectively, instead of duplicating the implementation.
Change-Id: I17551ea54c59c1e45ce472e029c625093a67251a
GitHub-Last-Rev: fecf43d163
GitHub-Pull-Request: golang/go#33390
Reviewed-on: https://go-review.googlesource.com/c/go/+/188397
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>