When T is a scalar, there are no runtime calls
required, which makes this a clear win.
encoding/binary:
WriteInts-8 958ns ± 3% 864ns ± 2% -9.80% (p=0.000 n=15+15)
This also considerably shrinks a core fmt
routine:
Before: "".(*pp).printArg t=1 size=3952 args=0x20 locals=0xf0
After: "".(*pp).printArg t=1 size=2624 args=0x20 locals=0x98
Unfortunately, I find it very hard to get stable
numbers out of the fmt benchmarks due to thermal scaling.
Change-Id: I1278006b030253bf8e48dc7631d18985cdaa143d
Reviewed-on: https://go-review.googlesource.com/26659
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Keith Randall <khr@golang.org>
We already inlined
_, ok = e.(T)
_, ok = i.(E)
_, ok = e.(E)
The only ok-only variants not inlined are now
_, ok = i.(I)
_, ok = e.(I)
These call getitab, so are non-trivial.
Change-Id: Ie45fd8933ee179a679b92ce925079b94cff0ee12
Reviewed-on: https://go-review.googlesource.com/26658
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
When a wrapper method calls the real implementation, it's not possible to use a
tail call when dynamic linking on ppc64le. The bad scenario is when a local
call is made to the wrapper: the wrapper will call the implementation, which
might be in a different module and so set the TOC to the appropriate value for
that module. But if it returns directly to the wrapper's caller, nothing will
reset it to the correct value for that function.
Change-Id: Icebf24c9a2a0a9a7c2bce6bd6f1358657284fb10
Reviewed-on: https://go-review.googlesource.com/23468
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
As in the elimination of PHEAP|PPARAM in CL 23393,
this is something the front end can trivially take care of
and then not bother the back ends with.
It also eliminates some suspect (and only lightly exercised)
code paths in the back ends.
I don't have a smoking gun for this one but it seems
more clearly correct.
Change-Id: I3b3f5e669b3b81d091ff1e2fb13226a6f14c69d5
Reviewed-on: https://go-review.googlesource.com/23431
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
The liveness computation of parameters generally was never
correct, but forcing all parameters to be live throughout the
function covered up that problem. The new SSA back end is
too clever: even though it currently keeps the parameter values live
throughout the function, it may find optimizations that mean
the current values are not written back to the original parameter
stack slots immediately or ever (for example if a parameter is set
to nil, SSA constant propagation may replace all later uses of the
parameter with a constant nil, eliminating the need to write the nil
value back to the stack slot), so the liveness code must now
track the actual operations on the stack slots, exposing these
problems.
One small problem in the handling of arguments is that nodarg
can return ONAME PPARAM nodes with adjusted offsets, so that
there are actually multiple *Node pointers for the same parameter
in the instruction stream. This might be possible to correct, but
not in this CL. For now, we fix this by using n.Orig instead of n
when considering PPARAM and PPARAMOUT nodes.
The major problem in the handling of arguments is general
confusion in the liveness code about the meaning of PPARAM|PHEAP
and PPARAMOUT|PHEAP nodes, especially as contrasted with PAUTO|PHEAP.
The difference between these two is that when a local variable "moves"
to the heap, it's really just allocated there to start with; in contrast,
when an argument moves to the heap, the actual data has to be copied
there from the stack at the beginning of the function, and when a
result "moves" to the heap the value in the heap has to be copied
back to the stack when the function returns
This general confusion is also present in the SSA back end.
The PHEAP bit worked decently when I first introduced it 7 years ago (!)
in 391425ae. The back end did nothing sophisticated, and in particular
there was no analysis at all: no escape analysis, no liveness analysis,
and certainly no SSA back end. But the complications caused in the
various downstream consumers suggest that this should be a detail
kept mainly in the front end.
This CL therefore eliminates both the PHEAP bit and even the idea of
"heap variables" from the back ends.
First, it replaces the PPARAM|PHEAP, PPARAMOUT|PHEAP, and PAUTO|PHEAP
variable classes with the single PAUTOHEAP, a pseudo-class indicating
a variable maintained on the heap and available by indirecting a
local variable kept on the stack (a plain PAUTO).
Second, walkexpr replaces all references to PAUTOHEAP variables
with indirections of the corresponding PAUTO variable.
The back ends and the liveness code now just see plain indirected
variables. This may actually produce better code, but the real goal
here is to eliminate these little-used and somewhat suspect code
paths in the back end analyses.
The OPARAM node type goes away too.
A followup CL will do the same to PPARAMREF. I'm not sure that
the back ends (SSA in particular) are handling those right either,
and with the framework established in this CL that change is trivial
and the result clearly more correct.
Fixes#15747.
Change-Id: I2770b1ce3cbc93981bfc7166be66a9da12013d74
Reviewed-on: https://go-review.googlesource.com/23393
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Non-syntax errors are always counted to determine if to exit
early, but then deduplication eliminates them. This can lead
to situations which report "too many errors" and only one
error is shown.
De-duplicate non-syntax errors early, at least the ones that
appear consecutively, and only count the ones actually being
shown. This doesn't work perfectly as they may not appear in
sequence, but it's cheap and good enough.
Fixes#14136.
Change-Id: I7b11ebb2e1e082f0d604b88e544fe5ba967af1d7
Reviewed-on: https://go-review.googlesource.com/23259
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
It never makes sense to CSE two ops that generate memory.
We might as well start those ops off in their own partition.
Fixes#15520
Change-Id: I0091ed51640f2c10cd0117f290b034dde7a86721
Reviewed-on: https://go-review.googlesource.com/22741
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Updates #15462
Automatic refactor with sed -e.
Replace all oconv(op, 0) to string conversion with the raw op value
which fmt's %v verb can print directly.
The remaining oconv(op, FmtSharp) will be replaced with op.GoString and
%#v in the next CL.
Change-Id: I5e2f7ee0bd35caa65c6dd6cb1a866b5e4519e641
Reviewed-on: https://go-review.googlesource.com/22499
Run-TryBot: Dave Cheney <dave@cheney.net>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Updates #15462
Semi automatic change with gofmt -r and hand fixups for callers outside
internal/gc.
All the uses of gc.Oconv outside cmd/compile/internal/gc were for the
Oconv(op, 0) form, which is already handled the Op.String method.
Replace the use of gc.Oconv(op, 0) with op itself, which will call
Op.String via the %v or %s verb. Unexport Oconv.
Change-Id: I84da2a2e4381b35f52efce427b2d6a3bccdf2526
Reviewed-on: https://go-review.googlesource.com/22496
Run-TryBot: Dave Cheney <dave@cheney.net>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
As a nice side-effect, this allows us to
unify several code paths.
The terminology (low, high, max, simple slice expr,
full slice expr) is taken from the spec and
the examples in the spec.
This is a trial run. The plan, probably for Go 1.8,
is to change slice expressions to use Node.List
instead of OKEY, and to do some similar
tree structure changes for other ops.
Passes toolstash -cmp. No performance change.
all.bash passes with GO_GCFLAGS=-newexport.
Updates #15350
Change-Id: Ic1efdc36e79cdb95ae1636e9817a3ac8f83ab1ac
Reviewed-on: https://go-review.googlesource.com/22425
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Instead of using TARRAY for both arrays and slices, create a new
TSLICE kind to handle slices.
Also, get rid of the "DDDArray" distinction. While kinda ugly, it
seems likely we'll need to defer evaluating the constant bounds
expressions for golang.org/issue/13890.
Passes toolstash/buildall.
Change-Id: I8e45d4900e7df3a04cce59428ec8b38035d3cc3a
Reviewed-on: https://go-review.googlesource.com/22329
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Some of the Debug[x] flags are actually boolean too, but not all, so
they need to be handled separately.
While here, change some obj.Flagstr and obj.Flagint64 calls to
directly use flag.StringVar and flag.Int64Var instead.
Change-Id: Iccedf6fed4328240ee2257f57fe6d66688f237c4
Reviewed-on: https://go-review.googlesource.com/22052
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Map keys are currently validated in multiple locations but share
a common validation routine. The problem is that early validations
should be lenient enough to allow for forward types while the final
validations should not. The final validations should fail on forward
types since they've already settled.
This change also separates the key type checking from the creation
of the map via typMap. Instead of the mapqueue being populated in
copytype() by checking the map line number, it's populated in the
same block that validates the key type. This isolates key validation
logic while type checking.
Fixes#14988
Change-Id: Ia47cf6213585d6c63b3a35249104c0439feae658
Reviewed-on: https://go-review.googlesource.com/21830
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Relatively few types are ever used as map keys,
so tracking this separately is a net win.
Passes toolstash -cmp.
name old alloc/op new alloc/op delta
Template 55.9MB ± 0% 55.5MB ± 0% -0.71% (p=0.000 n=10+10)
Unicode 37.8MB ± 0% 37.7MB ± 0% -0.27% (p=0.000 n=10+10)
GoTypes 180MB ± 0% 179MB ± 0% -0.52% (p=0.000 n=7+10)
Compiler 806MB ± 0% 803MB ± 0% -0.41% (p=0.000 n=10+10)
CPU and number of allocs are unchanged.
Change-Id: I6d60d74a4866995a231dfed3dd5792d75d904292
Reviewed-on: https://go-review.googlesource.com/21622
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Replace isideal(t) with t.IsUntyped().
Replace Istype(t, k) with t.IsKind(k).
Replace isnilinter(t) with t.IsEmptyInterface().
Also replace a lot of t.IsKind(TFOO) with t.IsFoo().
Replacements prepared mechanically with gofmt -w -r.
Passes toolstash -cmp.
Change-Id: Iba48058f3cc863e15af14277b5ff5e729e67e043
Reviewed-on: https://go-review.googlesource.com/21424
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This allows us to get rid of Isptr and Issigned. Still some code to
clean up for Isint, Isfloat, and Iscomplex.
CL produced mechanically using gofmt -w -r.
Passes toolstash -cmp.
Change-Id: If4f807bb7f2b357288d2547be2380eb511875786
Reviewed-on: https://go-review.googlesource.com/21339
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Replace Isfixedarray, Isslice, and Isinter with the IsArray, IsSlice,
and IsInterface methods added for SSA. Rewrite performed mechanically
using gofmt -w -r "Isfoo(t) -> t.IsFoo()".
Because the IsFoo methods panic when given a nil pointer, a handful of
call sites had to be modified to check for nil Type values. These
aren't strictly necessary, because nil Type values should only occur
in invalid Go source programs, so it would be okay if we panicked on
them and gave up type checking the rest of the package. However, there
are a couple regress tests that expect we continue, so add checks to
keep those tests passing. (See #15029.)
Passes toolstash -cmp.
Change-Id: I511c6ac4cfdf3f9cbdb3e52a5fa91b6d09d82f80
Reviewed-on: https://go-review.googlesource.com/21336
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This removes almost all direct access to
Type’s heavily overloaded Type field.
Mostly generated by eg, manually checked.
Significant manual changes:
* reflect.go's typPkg used Type indiscriminately.
Use it only for specific etypes.
* gen.go's visitComponents contained a usage of Type
with structs. Using Type for structs no longer
occurs, and the Fatal contained therein has not triggered,
so it has been axed.
* Scary code in cgen.go's cgen_slice is now explicitly scary.
Passes toolstash -cmp.
Change-Id: I2dbfb3c959da7ae239f964d83898c204affcabc6
Reviewed-on: https://go-review.googlesource.com/21331
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Also, add two uses of Key and Val that I missed earlier.
As before, direct writes to Down and Type remain in bimport.
Change-Id: I487aa975926b30092db1ad74ace17994697117c1
Reviewed-on: https://go-review.googlesource.com/21330
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Changes generated by eg and manually checked.
Isfixedarray, Isslice, and many other
Type-related functions in subr.go should
either be deleted or moved to type.go.
Later, though; the game now is cleanup via encapsulation.
Passes toolstash -cmp.
Change-Id: I83dd8816f6263b74367d23c2719a08c362e330f9
Reviewed-on: https://go-review.googlesource.com/21303
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
substAny needs access to many internal details
of gc.Type. substArgTypes comes along for the ride.
Change-Id: I430a4edfd54a1266522f7a9818e5e7b5da72479c
Reviewed-on: https://go-review.googlesource.com/21250
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
These are the first of several convenience
constructors for types.
They are part of type field encapsulation.
This removes most external writes to TARRAY Type and Bound fields.
substAny still directly fiddles with the .Type field.
substAny generally needs access to Type internals.
It will be moved to type.go in a future CL.
bimport still directly writes the .Type field.
This is hard to change.
Also of note:
* inl.go contains an (apparently irrelevant) bug fix:
as.Right was given the wrong type.
vararrtype was previously unused.
* I believe that aindex (subr.go) never creates slices,
but it is safer to keep existing behavior.
The removal of -1 as a constant there is part
of hiding that implementation detail.
Future CLs will finish that job.
Passes toolstash -cmp.
Change-Id: If09bf001a874d7dba08e9ad0bcd6722860af4b91
Reviewed-on: https://go-review.googlesource.com/21249
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This mostly a mechanical change.
However, the change in assignop (subr.go) is a bug fix.
The code didn’t match the comment,
and the comment was correct.
Nevertheless, this CL passes toolstash -cmp.
The last direct reference to dddBound outside
type.go (in typecheck.go) will go away
in a future CL.
Change-Id: Ifb1691e0a07f906712c18c4a4cd23060807a5da5
Reviewed-on: https://go-review.googlesource.com/21235
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Now that structs use a slice to store their fields, this code can be
simplified somewhat.
Passes toolstash -cmp.
Change-Id: If17b1c89871fa06f34938fa67df0f8c6bcf1a86b
Reviewed-on: https://go-review.googlesource.com/21219
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Also give them more idiomatic Go names. Adding godocs is outside the
scope of this CL. (Besides, the method names almost all directly
parallel an underlying math/big.Int or math/big.Float method.)
CL prepared mechanically with sed (for rewriting mpint.go/mpfloat.go)
and gofmt (for rewriting call sites).
Passes toolstash -cmp.
Change-Id: Id76f4aee476ba740f48db33162463e7978c2083d
Reviewed-on: https://go-review.googlesource.com/20909
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
The Node type ODOT and its variants all represent a selector, with a
simple name to the right of the dot. Before this change this was
represented by using an ONAME Node in the Right field. This ONAME node
served no useful purpose. This CL changes these Node types to store the
symbol in the Sym field instead, thus not requiring allocating a Node
for each selector.
When compiling x/tools/go/types this CL eliminates nearly 5000 calls to
newname and reduces the total number of Nodes allocated by about 6.6%.
It seems to cut compilation time by 1 to 2 percent.
Getting this right was somewhat subtle, and I added two dubious changes
to produce the exact same output as before. One is to ishairy in
inl.go: the ONAME node increased the cost of ODOT and friends by 1, and
I retained that, although really ODOT is not more expensive than any
other node. The other is to varexpr in walk.go: because the ONAME in
the Right field of an ODOT has no class, varexpr would always return
false for an ODOT, although in fact for some ODOT's it seemingly ought
to return true; I added an && false for now. I will send separate CLs,
that will break toolstash -cmp, to clean these up.
This CL passes toolstash -cmp.
Change-Id: I4af8a10cc59078c436130ce472f25abc3a9b2f80
Reviewed-on: https://go-review.googlesource.com/20890
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>