There's not really any use to tracking function-scoped constants and
types on Curfn.Dcl, and there's sloppy code that assumes all of the
declarations are variables (e.g., cmpstackvarlt).
Change-Id: I5d10dc681dac2c161c7b73ba808403052ca0608e
Reviewed-on: https://go-review.googlesource.com/c/go/+/274436
Reviewed-by: Russ Cox <rsc@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
This CL introduces types.NewBasic, for creating the predeclared
universal types, and reorganizes how the universe is initialized so
that all predeclared types are uniformly constructed.
There are now a bunch of Type fields that are no longer assigned
outside of the package, so this CL also introduces some new accessor
methods that a subsequent CL will mechanically introduce uses of.
Change-Id: Ie7996c3d5f1ca46cd5bfe45ecc91ebfa6a7b6c7d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274435
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
The start of abstracting away Type fields. This adds a new constructor
for named types, styled after go/types.NewNamed. Along with helper
methods for SetNod and Pos, this allows hiding Nod.
Change-Id: Ica107034b6346c7b523bf6ae2a34009e350a9aa8
Reviewed-on: https://go-review.googlesource.com/c/go/+/274434
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Now that setUnderlying is decoupled from Nodes, it can be moved into
package types, where it really belongs.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
mv setUnderlying SetUnderlying
mv SetUnderlying typex.go
mv typex.go cmd/compile/internal/types
'
cd ../types
rf '
mv typex.go type.go
'
Change-Id: I76e2d4d8a6df599f24a731c4d8e5774ec83a119c
Reviewed-on: https://go-review.googlesource.com/c/go/+/274433
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
The code for type-checking defined types was scattered between
typecheckdef, typecheckdeftype, and setUnderlying. There was redundant
work between them, and setUnderlying also needed to redo a lot of work
because of its brute-force solution of just copying all Type fields.
This CL reorders things so as many of the defined type's fields are
set in advance (in typecheckdeftype), and then setUnderlying only
copies over the details actually needed from the underlying type.
Incidentally, this evidently improves our error handling for an
existing test case, by allowing us to report an additional error.
Passes toolstash/buildall.
Change-Id: Id59a24341e7e960edd1f7366c3e2356da91b9fe7
Reviewed-on: https://go-review.googlesource.com/c/go/+/274432
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Allows emitting errors about ineffectual //go:linkname directives.
In particular, this exposed: a typo in os2_aix.go; redundant (but
harmless) directives for libc_pipe in both os3_solaris.go and
syscall2_solaris.go; and a bunch of useless //go:linkname directives
in macOS wrapper code.
However, because there's also ineffectual directives in the vendored
macOS code from x/sys, that can't be an error just yet. So instead we
print a warning (including a heads up that it will be promoted to an
error in Go 1.17) to prevent backsliding while we fix and re-vendor
that code.
Passes toolstash-check.
Change-Id: I59badeab5df0d8b3abfd14c6066e9bb00e840f73
Reviewed-on: https://go-review.googlesource.com/c/go/+/273986
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
RawCopy breaks the invariant that ir.Orig depends on for
allowing nodes to omit keeping their own orig fields.
Avoid surprises by unexporting it.
The only use in package gc was removed in the previous CL.
This one is a straight global search and replace RawCopy -> rawCopy.
Change-Id: Ia99c0f4665bf7ed4f878cc44456d5fbdf33bab8d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274293
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
The ONIL export bug happened because the logic about
maintaining an “implicit” orig pointer in the comments
around ir.Orig only applies to Copy and SepCopy, not to
direct use of RawCopy. I'd forgotten those could exist.
The sole direct use of RawCopy was for the OLITERAL/ONIL case.
The ONIL is now provably indistinguishable from Copy, since
NilExpr does not have an explicit Orig field, so for NilExpr
RawCopy and Copy are the same.
The OLITERAL is not, but we can reconstruct the effect
with Copy+SetOrig to be explicit that we need the orig link.
The next CL will unexport RawCopy.
Also fix a typo in MapType doc comment.
Passes buildall w/ toolstash -cmp.
Change-Id: I876a85ff188e6d1cd4c0dfa385be32482e0de0d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/274292
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
When checking if a defined type is part of a type loop, we can
short-circuit if it was defined in another package. We can assume any
package we import already successfully compiled, so any types it
contains cannot be part of a type loop.
This also allows us to simplify the logic for recursing into the type
used in the type declaration, because any defined type from this
package will have a properly setup node.
Change-Id: Ic024814d95533afd9e59f2103c8ddb22bd87e900
Reviewed-on: https://go-review.googlesource.com/c/go/+/274294
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
This CL only adds the new constant, which is not safe for toolstash -cmp.
Change-Id: I774463a0ab5f57113d67a8888b6ac787be68510c
Reviewed-on: https://go-review.googlesource.com/c/go/+/274110
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
These are fairly rote implementations of structs appropriate to
each Op (or group of Ops).
The names of these are unknown except to ir.NodAt for now.
A later, automated change will introduce direct use of the types
throughout package gc.
(This CL is expressions; the previous one was statements.)
This is the last of the Ops that were previously handled by the
generic node struct, so that struct and its methods can be
and are deleted in this CL.
Passes buildall w/ toolstash -cmp.
Change-Id: I1703f35f24dcd3f7c5782a278e53c3fe04e87c37
Reviewed-on: https://go-review.googlesource.com/c/go/+/274109
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
It's not types's responsibility to understand how package
initialization is implemented. Instead, have gc keep track of the
order that packages were imported, and then look for inittask
declarations.
Also, use resolve to force importing of the inittask's export data, so
that we can get the appropriate linker symbol index. (This is also why
this CL doesn't satisfy "toolstash -cmp".)
Change-Id: I5b706497d4a8d1c4439178863b4a8dba4da0f5a9
Reviewed-on: https://go-review.googlesource.com/c/go/+/274006
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
The compile -h flag is *meant* to panic, so you can see the stack
trace where the error is being printed. Make it do that again.
Change-Id: Ieb0042863582d7a4c5d08d2f866a144962915b06
Reviewed-on: https://go-review.googlesource.com/c/go/+/274116
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
These are fairly rote implementations of structs appropriate to
each Op (or group of Ops).
The names of these are unknown except to ir.NodAt for now.
A later, automated change will introduce direct use of the types
throughout package gc.
Passes buildall w/ toolstash -cmp.
Change-Id: Ie9835fcd2b214fda5b2149e187af369d76534487
Reviewed-on: https://go-review.googlesource.com/c/go/+/274108
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
The list is no longer needed and can be deleted.
Doing so reduces the inlining cost of any function containing
an explicit call to new by 1 point, so this change is not
toolstash -cmp safe.
Change-Id: Id29e115d68e466a353708ab4b8c1021e9c85a628
Reviewed-on: https://go-review.googlesource.com/c/go/+/274132
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Using expression nodes restricts the set of valid SetOp operations,
because you can't SetOp across representation. Rewrite various code
to avoid crossing those as-yet-unintroduced boundaries.
This also includes choosing a single representation for any given Op.
For example, OCLOSE starts out as an OCALL, so it starts with a List
of one node and then moves that node to Left. That's no good with
real data structures, so the code picks a single canonical implementation
and prepares it during the conversion from one Op to the next.
In this case, the conversion of an OCALL to an OCLOSE now creates
a new node with Left initialized from the start. This pattern repeats.
Passes buildall w/ toolstash -cmp.
Change-Id: I55a0872c614d883cac9d64976c46aeeaa639e25d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274107
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Just a little cleaner to read.
Passes buildall w/ toolstash -cmp.
Change-Id: I27b9f09bf6756f74f1c01794444518ded1a7d625
Reviewed-on: https://go-review.googlesource.com/c/go/+/274106
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Using statement nodes restricts the set of valid SetOp operations,
because you can't SetOp across representation. Rewrite various
code to avoid crossing those as-yet-unintroduced boundaries.
In particular, code like
x, y := v.(T)
x, y := f()
x, y := m[k]
x, y := <-c
starts out with Op = OAS2, and then it turns into a specific Op
OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV, and then
later in walk is lowered to an OAS2 again.
In the middle, the specific forms move the right-hand side from
n.Rlist().First() to n.Right(), and then the conversion to OAS2 moves
it back. This is unnecessary and makes it hard for these all to
share an underlying Node implementation.
This CL changes these specific forms to leave the right-hand side
in n.Rlist().First().
Similarly, OSELRECV2 is really just a temporary form of OAS2.
This CL changes it to use same fields too.
Finally, this CL fixes the printing of OAS2 nodes in ir/fmt.go,
which formerly printed n.Right() instead of n.Rlist().
This results in a (correct!) update to cmd/compile/internal/logopt's
expected output: ~R0 = <N> becomes ~R0 = &y.b.
Passes buildall w/ toolstash -cmp.
Change-Id: I164aa2e17dc55bfb292024de53d7d250192ad64a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274105
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
The handling of ONIL and Orig has been a mess for a while, and dates
back to how fmt.go used to print out typed nils. That hasn't applied
for a while, but we've kept dragging it along to appease toolstash
with the intention of someday finally removing it.
Today is that day.
Change-Id: I9a441628e53068ab1993cd2b67b977574d8117b7
Reviewed-on: https://go-review.googlesource.com/c/go/+/274212
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
These are plain data now, not nodes (see previous CL).
The opcode deletions are not safe for toolstash -cmp,
so they are split into a separate CL.
Change-Id: Icef8a01e190195a7539a35b92f42835d823e314a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274104
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
The type syntax is reused to stand in for the actual type once typechecked,
to avoid updating all the possible references to the original type syntax.
So all these implementations allow changing their Op from the raw syntax
like OTMAP to the finished form OTYPE, even though obviously the
representation does not change.
Passes buildall w/ toolstash -cmp.
Change-Id: I4acca1a5b35fa2f48ee08e8f1e5a330a004c284b
Reviewed-on: https://go-review.googlesource.com/c/go/+/274103
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
This is a general operation on IR nodes, so it belongs in ir.
The copied implementation is adapted to support the
extension pattern, allowing nodes to implement their
own DeepCopy implementations if needed.
This is the first step toward higher-level operations instead
of Left, Right, etc. It will allow the new type syntax nodes
to be properly immutable and opt out of those fine-grained methods.
Passes buildall w/ toolstash -cmp.
Change-Id: Ibd64061e01daf14aebc6586cb2eb2b12057ca85a
Reviewed-on: https://go-review.googlesource.com/c/go/+/274102
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This is not safe for toolstash -cmp and so is split into its own CL.
Change-Id: Ic3254e68fb84a90a11ac5f0b59ef252135c23658
Reviewed-on: https://go-review.googlesource.com/c/go/+/274101
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Now there are no longer any generic nodes with a non-nil
associated Func, so node.fn can be deleted. Also all manipulation
of func fields is done with concrete types, so Node.SetFunc can be
deleted, along with generic implementations.
Passes buildall w/ toolstash -cmp.
Change-Id: I4fee99870951ec9dc224f146d87b22e2bfe16889
Reviewed-on: https://go-review.googlesource.com/c/go/+/274099
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Closures are another reference to Funcs,
and it cleans up the code quite a bit to be clear about types.
OCLOSUREVAR is renamed to OCLOSUREREAD to make
clearer that it is unrelated to the list Func.ClosureVars.
Passes buildall w/ toolstash -cmp.
Change-Id: Id0d28df2d4d6e9954e34df7a39ea226995eee937
Reviewed-on: https://go-review.googlesource.com/c/go/+/274098
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Now that we have specific types for ONAME and ODCLFUNC nodes
(*Name and *Func), use them throughout the compiler to be more
precise about what data is being operated on.
This is a somewhat large CL, but once you start applying the types
in a few places, you end up needing to apply them to many other
places to keep everything type-checking. A lot of code also melts
away as types are added.
Passes buildall w/ toolstash -cmp.
Change-Id: I21dd9b945d701c470332bac5394fca744a5b232d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274097
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Before this CL, an ODCLFUNC Node was represented by both
a node struct and a Func struct (and a Name for the ONAME,
which isn't changing here). Now Func can be repurposed as
the ODCLFUNC implementation, replacing the two structs
totaling 280+144 = 424 bytes (64-bit) with a single 320-byte struct.
Using the *Func as the node also gives us a clear, typed answer to
“which node should we use to represent functions?”
The next CL will clean up uses. This CL is just the trivial
change in representation.
Passes buildall w/ toolstash -cmp.
Change-Id: Ie6d670da91d6eb8d67a85f8f83630b9586dc7443
Reviewed-on: https://go-review.googlesource.com/c/go/+/274096
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
No code changes here, only copying of text.
This will make the diffs in a future CL readable.
Passes buildall w/ toolstash -cmp.
Change-Id: I325a62e79edd82f1437769891ea63a32f51c0170
Reviewed-on: https://go-review.googlesource.com/c/go/+/274095
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Before this CL, an ONAME Node was represented by three structs
linked together: a node, a Name, and a Param. Previous CLs removed
OLABEL and OPACK from the set of nodes that knew about Name.
Now Name can be repurposed to *be* the ONAME Node implementation,
replacing three linked structs totaling 152+64+88 = 304 bytes (64-bit)
with a single 232-byte struct.
Many expressions in the code become simpler as well, without having
to use .Param. and sometimes even .Name().
(For a node n where n.Name() != nil, n.Name() == n.(*Name) now.)
Passes buildall w/ toolstash -cmp.
Change-Id: Ie719f1285c05623b9fd2faaa059e5b360a64b3be
Reviewed-on: https://go-review.googlesource.com/c/go/+/274094
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
OPACK was using a whole Node and Name and Param
to hold about three fields. Give it its own implementation.
Passes buildall w/ toolstash -cmp.
Change-Id: I85a28b43d37183b2062d337b0b1b2eea52884e8c
Reviewed-on: https://go-review.googlesource.com/c/go/+/274093
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
No code changes here, only copying of text.
This will make the diffs in a future CL readable.
Passes buildall w/ toolstash -cmp.
Change-Id: I1b8d8b9ec9408859e36af5ff3bef7c6c10eac0d6
Reviewed-on: https://go-review.googlesource.com/c/go/+/274092
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
These are the first three specific implementations of Node.
They are both a bit of a warmup and also working toward
removing references to Name from Node types other than
the proper named things - ONAME, ONONAME, OTYPE, OLITERAL.
(In this case, BranchStmt and LabelStmt.)
Passes buildall w/ toolstash -cmp.
Change-Id: Ide816b162025ee4c858dd061d7c29ed633fb7baf
Reviewed-on: https://go-review.googlesource.com/c/go/+/274091
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
In preparation for OEMPTY being its own Node implementation,
remove SetOp(OEMPTY) calls that assume other implementations
can be turned into OEMPTY.
Passes buildall w/ toolstash -cmp.
Change-Id: Icac16d12548f35f52a5efa9d09dacf8260f42075
Reviewed-on: https://go-review.googlesource.com/c/go/+/274090
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
These are only needed for a few opcodes, and we can avoid
wasting storage in every implementation by using the extension
interface pattern with a helper function for access.
Of course, in the current codebase, there is only one Node
implementation (*node) and it has these methods, so there
is no danger of a functional change in this particular CL.
Passes buildall w/ toolstash -cmp.
Change-Id: I440c6c232f1fe7b56b852a00dc530f8f49a6b12d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274089
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Start a list of which ops are valid for the default
node struct implementation (currently all of them).
Add a Node implementation helper for a minimal node.
Passes buildall w/ toolstash -cmp.
Change-Id: I7ae45f2cf2be85013cb71ab00524be53f243e13d
Reviewed-on: https://go-review.googlesource.com/c/go/+/274088
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Node.HasOpt is only used once, and that use can use Opt instead.
Interface is one method smaller.
Passes buildall w/ toolstash -cmp.
Change-Id: I6a9d5859a9977a8f4c9db70e166f50f0d8052160
Reviewed-on: https://go-review.googlesource.com/c/go/+/274087
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
- The use of a label's Name.Defn to point at the named for/select/switch
means that any rewrite of the for/select/switch must overwrite the original
or else the pointer will dangle. Remove that pointer by adding the label
name directly to the for/select/switch representation instead.
- The only uses of a label's Sym.Label were ephemeral values during
markbreak and escape analysis. Use a map for each. Although in general
we are not going to replace all computed fields with maps (too slow),
the one in markbreak is only for labeled for/select/switch, and the one
in escape is for all labels, but even so, labels are fairly rare.
In theory this cleanup should make it easy to allow labeled for/select/switch
in inlined bodies, but this CL does not attempt that. It's only concerned
with cleanup to enable a new Node representation.
Passes buildall w/ toolstash -cmp.
Change-Id: I7e36ee98d2ea40dbae94e6722d585f007b7afcfa
Reviewed-on: https://go-review.googlesource.com/c/go/+/274086
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
In CL 145200, I changed OBREAK, OCONTINUE, OGOTO, and OLABEL to just
use Sym instead of Node. However, within the export data, I forgot to
update the code for OBREAK and OCONTINUE.
This isn't currently an issue because the inliner currently disallows
these anyway, but it'll be an issue in the future once we add support
for inlining them. Also, Russ independently ran into it in CL 273246.
Updates #14768.
Change-Id: I94575df59c08a750b0dce1d3ce612aba7bfeeb76
Reviewed-on: https://go-review.googlesource.com/c/go/+/273270
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Many of the standard library changes that were added before CL 272871
ended up in the "Core library" section. That section is meant for
major changes like new packages, and most of these aren't.
Consolidate all changes in the "Minor changes to the library" section
for now, so that it's easier to get a complete picture of changes for
each package, along with the remaining TODOs. Add a TODO to read them
over at the end and factor out items that are worth highlighting.
Apply minor other fixups to improve consistency.
For #40700.
Change-Id: I7dc2e7ebf2ea3385fce0c207bae4ce467998a717
Reviewed-on: https://go-review.googlesource.com/c/go/+/273267
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Katie Hockman <katie@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Fixes the android/arm builder. Without it, the builder reported
unexpected stale targets during bootstrap:
https://build.golang.org/log/b951f1171be54cf4a12c2a0720ffaf07f8a11377
Tighten the GOARM=7 default in cmd/internal/objabi while here.
Change-Id: I944744910193e72e91bc37b5bf0783076b45e579
Reviewed-on: https://go-review.googlesource.com/c/go/+/273167
Run-TryBot: Elias Naur <mail@eliasnaur.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Elias Naur <mail@eliasnaur.com>
The plan is to introduce a Node interface that replaces the old *Node pointer-to-struct.
The previous CL defined an interface INode modeling a *Node.
This CL:
- Changes all references outside internal/ir to use INode,
along with many references inside internal/ir as well.
- Renames Node to node.
- Renames INode to Node
So now ir.Node is an interface implemented by *ir.node, which is otherwise inaccessible,
and the code outside package ir is now (clearly) using only the interface.
The usual rule is never to redefine an existing name with a new meaning,
so that old code that hasn't been updated gets a "unknown name" error
instead of more mysterious errors or silent misbehavior. That rule would
caution against replacing Node-the-struct with Node-the-interface,
as in this CL, because code that says *Node would now be using a pointer
to an interface. But this CL is being landed at the same time as another that
moves Node from gc to ir. So the net effect is to replace *gc.Node with ir.Node,
which does follow the rule: any lingering references to gc.Node will be told
it's gone, not silently start using pointers to interfaces. So the rule is followed
by the CL sequence, just not this specific CL.
Overall, the loss of inlining caused by using interfaces cuts the compiler speed
by about 6%, a not insignificant amount. However, as we convert the representation
to concrete structs that are not the giant Node over the next weeks, that speed
should come back as more of the compiler starts operating directly on concrete types
and the memory taken up by the graph of Nodes drops due to the more precise
structs. Honestly, I was expecting worse.
% benchstat bench.old bench.new
name old time/op new time/op delta
Template 168ms ± 4% 182ms ± 2% +8.34% (p=0.000 n=9+9)
Unicode 72.2ms ±10% 82.5ms ± 6% +14.38% (p=0.000 n=9+9)
GoTypes 563ms ± 8% 598ms ± 2% +6.14% (p=0.006 n=9+9)
Compiler 2.89s ± 4% 3.04s ± 2% +5.37% (p=0.000 n=10+9)
SSA 6.45s ± 4% 7.25s ± 5% +12.41% (p=0.000 n=9+10)
Flate 105ms ± 2% 115ms ± 1% +9.66% (p=0.000 n=10+8)
GoParser 144ms ±10% 152ms ± 2% +5.79% (p=0.011 n=9+8)
Reflect 345ms ± 9% 370ms ± 4% +7.28% (p=0.001 n=10+9)
Tar 149ms ± 9% 161ms ± 5% +8.05% (p=0.001 n=10+9)
XML 190ms ± 3% 209ms ± 2% +9.54% (p=0.000 n=9+8)
LinkCompiler 327ms ± 2% 325ms ± 2% ~ (p=0.382 n=8+8)
ExternalLinkCompiler 1.77s ± 4% 1.73s ± 6% ~ (p=0.113 n=9+10)
LinkWithoutDebugCompiler 214ms ± 4% 211ms ± 2% ~ (p=0.360 n=10+8)
StdCmd 14.8s ± 3% 15.9s ± 1% +6.98% (p=0.000 n=10+9)
[Geo mean] 480ms 510ms +6.31%
name old user-time/op new user-time/op delta
Template 223ms ± 3% 237ms ± 3% +6.16% (p=0.000 n=9+10)
Unicode 103ms ± 6% 113ms ± 3% +9.53% (p=0.000 n=9+9)
GoTypes 758ms ± 8% 800ms ± 2% +5.55% (p=0.003 n=10+9)
Compiler 3.95s ± 2% 4.12s ± 2% +4.34% (p=0.000 n=10+9)
SSA 9.43s ± 1% 9.74s ± 4% +3.25% (p=0.000 n=8+10)
Flate 132ms ± 2% 141ms ± 2% +6.89% (p=0.000 n=9+9)
GoParser 177ms ± 9% 183ms ± 4% ~ (p=0.050 n=9+9)
Reflect 467ms ±10% 495ms ± 7% +6.17% (p=0.029 n=10+10)
Tar 183ms ± 9% 197ms ± 5% +7.92% (p=0.001 n=10+10)
XML 249ms ± 5% 268ms ± 4% +7.82% (p=0.000 n=10+9)
LinkCompiler 544ms ± 5% 544ms ± 6% ~ (p=0.863 n=9+9)
ExternalLinkCompiler 1.79s ± 4% 1.75s ± 6% ~ (p=0.075 n=10+10)
LinkWithoutDebugCompiler 248ms ± 6% 246ms ± 2% ~ (p=0.965 n=10+8)
[Geo mean] 483ms 504ms +4.41%
[git-generate]
cd src/cmd/compile/internal/ir
: # We need to do the conversion in multiple steps, so we introduce
: # a temporary type alias that will start out meaning the pointer-to-struct
: # and then change to mean the interface.
rf '
mv Node OldNode
add node.go \
type Node = *OldNode
'
: # It should work to do this ex in ir, but it misses test files, due to a bug in rf.
: # Run the command in gc to handle gc's tests, and then again in ssa for ssa's tests.
cd ../gc
rf '
ex . ../arm ../riscv64 ../arm64 ../mips64 ../ppc64 ../mips ../wasm {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
cd ../ssa
rf '
ex {
import "cmd/compile/internal/ir"
*ir.OldNode -> ir.Node
}
'
: # Back in ir, finish conversion clumsily with sed,
: # because type checking and circular aliases do not mix.
cd ../ir
sed -i '' '
/type Node = \*OldNode/d
s/\*OldNode/Node/g
s/^func (n Node)/func (n *OldNode)/
s/OldNode/node/g
s/type INode interface/type Node interface/
s/var _ INode = (Node)(nil)/var _ Node = (*node)(nil)/
' *.go
gofmt -w *.go
sed -i '' '
s/{Func{}, 136, 248}/{Func{}, 152, 280}/
s/{Name{}, 32, 56}/{Name{}, 44, 80}/
s/{Param{}, 24, 48}/{Param{}, 44, 88}/
s/{node{}, 76, 128}/{node{}, 88, 152}/
' sizeof_test.go
cd ../ssa
sed -i '' '
s/{LocalSlot{}, 28, 40}/{LocalSlot{}, 32, 48}/
' sizeof_test.go
cd ../gc
sed -i '' 's/\*ir.Node/ir.Node/' mkbuiltin.go
cd ../../../..
go install std cmd
cd cmd/compile
go test -u || go test -u
Change-Id: I196bbe3b648e4701662e4a2bada40bf155e2a553
Reviewed-on: https://go-review.googlesource.com/c/go/+/272935
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Define the interface for an IR node.
The next CL will shuffle the names and leave us with ir.Node being the interface.
Change-Id: Ifc40f7846d522cf99efa6b4e558bebb6db5218f9
Reviewed-on: https://go-review.googlesource.com/c/go/+/272934
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
The pointer hack was nice and saved a word, but it's untenable
in a world where nodes are themselves interfaces with different
underlying types. Bite the bullet and use an interface to hold the
Node when in types.Sym and types.Type.
This has the nice benefit of removing AsTypesNode entirely.
AsNode is still useful because of its nil handling.
Change-Id: I298cba9ff788b956ee287283bec78010e8b601e5
Reviewed-on: https://go-review.googlesource.com/c/go/+/272933
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
These are trivial rewrites that are only OK because it turns out that n has no side effects.
Separated into a different CL for easy inspection.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
ex . ../ir ../ssa {
import "cmd/compile/internal/ir"
var n *ir.Node
var i int64
n.Xoffset++ -> n.Xoffset = n.Xoffset + 1
n.Xoffset-- -> n.Xoffset = n.Xoffset - 1
n.Xoffset += i -> n.Xoffset = n.Xoffset + i
n.Xoffset -= i -> n.Xoffset = n.Xoffset - i
}
'
Change-Id: If7b4b7f7cbdafeee988e04d03924ef0e1dd867b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/272932
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
The cycle hacks existed because gc needed to import ssa
which need to know about gc.Node. But now that's ir.Node,
and there's no cycle anymore.
Don't know how much it matters but LocalSlot is now
one word shorter than before, because it holds a pointer
instead of an interface for the *Node. That won't last long.
Now that they're not necessary for interface satisfaction,
IsSynthetic and IsAutoTmp can move to top-level ir functions.
Change-Id: Ie511e93466cfa2b17d9a91afc4bd8d53fdb80453
Reviewed-on: https://go-review.googlesource.com/c/go/+/272931
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.
This CL is automatically generated by the script below.
See the comments in the script for details about the changes.
[git-generate]
cd src/cmd/compile/internal/gc
rf '
# These names were never fully qualified
# when the types package was added.
# Do it now, to avoid confusion about where they live.
inline -rm \
Txxx \
TINT8 \
TUINT8 \
TINT16 \
TUINT16 \
TINT32 \
TUINT32 \
TINT64 \
TUINT64 \
TINT \
TUINT \
TUINTPTR \
TCOMPLEX64 \
TCOMPLEX128 \
TFLOAT32 \
TFLOAT64 \
TBOOL \
TPTR \
TFUNC \
TSLICE \
TARRAY \
TSTRUCT \
TCHAN \
TMAP \
TINTER \
TFORW \
TANY \
TSTRING \
TUNSAFEPTR \
TIDEAL \
TNIL \
TBLANK \
TFUNCARGS \
TCHANARGS \
NTYPE \
BADWIDTH
# esc.go and escape.go do not need to be split.
# Append esc.go onto the end of escape.go.
mv esc.go escape.go
# Pull out the type format installation from func Main,
# so it can be carried into package ir.
mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats
# Names that need to be exported for use by code left in gc.
mv Isconst IsConst
mv asNode AsNode
mv asNodes AsNodes
mv asTypesNode AsTypesNode
mv basicnames BasicTypeNames
mv builtinpkg BuiltinPkg
mv consttype ConstType
mv dumplist DumpList
mv fdumplist FDumpList
mv fmtMode FmtMode
mv goopnames OpNames
mv inspect Inspect
mv inspectList InspectList
mv localpkg LocalPkg
mv nblank BlankNode
mv numImport NumImport
mv opprec OpPrec
mv origSym OrigSym
mv stmtwithinit StmtWithInit
mv dump DumpAny
mv fdump FDumpAny
mv nod Nod
mv nodl NodAt
mv newname NewName
mv newnamel NewNameAt
mv assertRepresents AssertValidTypeForConst
mv represents ValidTypeForConst
mv nodlit NewLiteral
# Types and fields that need to be exported for use by gc.
mv nowritebarrierrecCallSym SymAndPos
mv SymAndPos.lineno SymAndPos.Pos
mv SymAndPos.target SymAndPos.Sym
mv Func.lsym Func.LSym
mv Func.setWBPos Func.SetWBPos
mv Func.numReturns Func.NumReturns
mv Func.numDefers Func.NumDefers
mv Func.nwbrCalls Func.NWBRCalls
# initLSym is an algorithm left behind in gc,
# not an operation on Func itself.
mv Func.initLSym initLSym
mv nodeQueue NodeQueue
mv NodeQueue.empty NodeQueue.Empty
mv NodeQueue.popLeft NodeQueue.PopLeft
mv NodeQueue.pushRight NodeQueue.PushRight
# Many methods on Node are actually algorithms that
# would apply to any node implementation.
# Those become plain functions.
mv Node.funcname FuncName
mv Node.isBlank IsBlank
mv Node.isGoConst isGoConst
mv Node.isNil IsNil
mv Node.isParamHeapCopy isParamHeapCopy
mv Node.isParamStackCopy isParamStackCopy
mv Node.isSimpleName isSimpleName
mv Node.mayBeShared MayBeShared
mv Node.pkgFuncName PkgFuncName
mv Node.backingArrayPtrLen backingArrayPtrLen
mv Node.isterminating isTermNode
mv Node.labeledControl labeledControl
mv Nodes.isterminating isTermNodes
mv Nodes.sigerr fmtSignature
mv Node.MethodName methodExprName
mv Node.MethodFunc methodExprFunc
mv Node.IsMethod IsMethod
# Every node will need to implement RawCopy;
# Copy and SepCopy algorithms will use it.
mv Node.rawcopy Node.RawCopy
mv Node.copy Copy
mv Node.sepcopy SepCopy
# Extract Node.Format method body into func FmtNode,
# but leave method wrapper behind.
mv Node.Format:0,$ FmtNode
# Formatting helpers that will apply to all node implementations.
mv Node.Line Line
mv Node.exprfmt exprFmt
mv Node.jconv jconvFmt
mv Node.modeString modeString
mv Node.nconv nconvFmt
mv Node.nodedump nodeDumpFmt
mv Node.nodefmt nodeFmt
mv Node.stmtfmt stmtFmt
# Constant support needed for code moving to ir.
mv okforconst OKForConst
mv vconv FmtConst
mv int64Val Int64Val
mv float64Val Float64Val
mv Node.ValueInterface ConstValue
# Organize code into files.
mv LocalPkg BuiltinPkg ir.go
mv NumImport InstallTypeFormats Line fmt.go
mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
AsNode AsTypesNode BlankNode OrigSym \
Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
Node.RawCopy SepCopy Copy \
IsNil IsBlank IsMethod \
Node.Typ Node.StorageClass node.go
mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go
# Move files to new ir package.
mv bitset.go class_string.go dump.go fmt.go \
ir.go node.go op_string.go val.go \
sizeof_test.go cmd/compile/internal/ir
'
: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
s/\[T/[types.T/g
s/\*Node/*ir.Node/g
/internal\/types/c \
fmt.Fprintln(&b, `import (`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/ir"`) \
fmt.Fprintln(&b, ` "cmd/compile/internal/types"`) \
fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go
: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
"cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go
: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test # first one updates but fails; second passes
Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
It needs to move into package ir, and we do not want all the rest.
Change-Id: Ibcfa1ebc0e63fe3659267bf2fa7069e8a93de4e9
Reviewed-on: https://go-review.googlesource.com/c/go/+/272930
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>