This CL changes the heuristic used to determine whether we can inline a
struct equality check or if we must generate a function and call that
function for equality.
The old method was to count struct fields, but this can lead to poor
in lining decisions. We should really be determining the cost of the
equality check and use that to determine if we should inline or generate
a function.
The new benchmark provided in this CL returns the following when compared
against tip:
```
name old time/op new time/op delta
EqStruct-32 2.46ns ± 4% 0.25ns ±10% -89.72% (p=0.000 n=39+39)
```
Fixes#38494
Change-Id: Ie06b80a2b2a03a3fd0978bcaf7715f9afb66e0ab
GitHub-Last-Rev: e9a18d9389
GitHub-Pull-Request: golang/go#53326
Reviewed-on: https://go-review.googlesource.com/c/go/+/411674
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This CL optimizes RotateLeft8/16 on arm64.
For 16 bits, we form a 32 bits register by duplicating two 16 bits
registers, then use RORW instruction to do the rotate shift.
For 8 bits, we just use LSR and LSL instead of RORW because the code is
simpler.
Benchmark Old ThisCL delta
RotateLeft8-46 2.16 ns/op 1.73 ns/op -19.70%
RotateLeft16-46 2.16 ns/op 1.54 ns/op -28.53%
Change-Id: I09cde4383d12e31876a57f8cdfd3bb4f324fadb0
Reviewed-on: https://go-review.googlesource.com/c/go/+/420976
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
So they can be added to ignored list, since the tests now require
cgo.Incomplete, which is not recognized by go/types and types2.
Updates #46731
Change-Id: I9f24e3c8605424d1f5f42ae4409437198f4c1326
Reviewed-on: https://go-review.googlesource.com/c/go/+/427142
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
For the following code case:
var x uint64
x >> (shift & 63)
We can directly genereta `x >> shift` on arm64, since the hardware will
only use the bottom 6 bits of the shift amount.
Benchmark old time/op new time/op delta
ShiftArithmeticRight-8 0.40ns 0.31ns -21.7%
Change-Id: Id58c8a5b2f6dd5c30c3876f4a36e11b4d81e2dc9
Reviewed-on: https://go-review.googlesource.com/c/go/+/425294
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
On AIX when external linking, for some symbols we need to add
dummy references to prevent the external linker from discarding
them. Currently we add the reference unconditionally. But if the
symbol doesn't exist, the linking fails in a later stage for
generating external relocation of a nonexistent symbol. The
symbols are special symbols that almost always exist, except that
go:buildid may not exist if the linker is invoked without the
-buildid flag. The go command invokes the linker with the flag, so
this can only happen with manual linker invocation. Specifically,
test/run.go does this in some cases.
Fix this by checking the symbol existence before adding the
reference. Re-enable tests on AIX.
Perhaps the linker should always emit a dummy buildid even if the
flag is not set...
Fixes#54814.
Change-Id: I43d81587151595309e189e38960cbda9a1c5ca32
Reviewed-on: https://go-review.googlesource.com/c/go/+/427620
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
So it won't be visible outside of runtime package. There are changes to
make tests happy:
- For test/directive*.go files, using "go:noinline" for testing misplaced
directives instead.
- Restrict test/fixedbugs/bug515.go for gccgo only.
- For test/notinheap{2,3}.go, using runtime/cgo.Incomplete for marking
the type as not-in-heap. Though it's somewhat clumsy, it's the easiest
way to keep the test errors for not-in-heap types until we can cleanup
further.
- test/typeparam/mdempsky/11.go is about defined type in user code marked
as go:notinheap, which can't happen after this CL, though.
Fixes#46731
Change-Id: I869f5b2230c8a2a363feeec042e7723bbc416e8e
Reviewed-on: https://go-review.googlesource.com/c/go/+/421882
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
The syntax for go and defer specifies an arbitrary expression, not
a call; the call requirement is spelled out in prose. Don't to the
call check in the parser; instead move it to the type checker. This
is simpler and also allows the type checker to check expressions that
are not calls, and avoid "not used" errors due to such expressions.
We would like to make the same change in go/parser and go/types
but the change requires Go/DeferStmt nodes to hold an ast.Expr
rather than an *ast.CallExpr. We cannot change that for backward-
compatibility reasons. Since we don't test this behavior for the
type checkers alone (only for the compiler), we get away with it
for now.
Follow-up on CL 425675 which introduced the extra errors in the
first place.
Change-Id: I90890b3079d249bdeeb76d5673246ba44bec1a7b
Reviewed-on: https://go-review.googlesource.com/c/go/+/425794
Reviewed-by: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
- Use "expected X" rather then "expecting X".
- Report a better error when a type argument list is expected.
- Adjust various tests.
For #54511.
Change-Id: I0c5ca66ecbbdcae1a8f67377682aae6b0b6ab89a
Reviewed-on: https://go-review.googlesource.com/c/go/+/425734
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
If the go/defer syntax is bad, using a fake CallExpr may produce
a follow-on error in the type checker. Instead store a BadExpr
in the syntax tree (since an error has already been reported).
Adjust various tests.
For #54511.
Change-Id: Ib2d25f8eab7d5745275188d83d11620cad6ef47c
Reviewed-on: https://go-review.googlesource.com/c/go/+/425675
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Since when go/types,types2 do not know about build constraints, and
runtime/cgo.Incomplete is only available on platforms that support cgo.
These tests are also failing on aix with failure from linker, so disable
them on aix to make builder green. The fix for aix is tracked in #54814
Updates #46731
Updates #54814
Change-Id: I5d6f6e29a8196efc6c457ea64525350fc6b20309
Reviewed-on: https://go-review.googlesource.com/c/go/+/427394
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Same as CL 421880, but for test directory.
Updates #46731
Change-Id: If8d18df013a6833adcbd40acc1a721bbc23ca6b2
Reviewed-on: https://go-review.googlesource.com/c/go/+/421881
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
After running the types2 type checker, walk info.Instances to reject
any not-in-heap type arguments. This is feasible to check using the
types2 API now, thanks to #46731.
Fixes#54765.
Change-Id: Idd2acc124d102d5a76f128f13c21a6e593b6790b
Reviewed-on: https://go-review.googlesource.com/c/go/+/427235
Reviewed-by: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Rotating by c, then by d, is the same as rotating by c+d.
Change-Id: I36df82261460ff80f7c6d39bcdf0e840cef1c91a
Reviewed-on: https://go-review.googlesource.com/c/go/+/424894
Reviewed-by: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ruinan Sun <Ruinan.Sun@arm.com>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Currently we use a full cmpstring to do the comparison for each
split in the binary search for a string switch.
Instead, split by comparing a single byte of the input string with a
constant. That will give us a much faster split (although it might be
not quite as good a split).
Fixes#53333
R=go1.20
Change-Id: I28c7209342314f367071e4aa1f2beb6ec9ff7123
Reviewed-on: https://go-review.googlesource.com/c/go/+/414894
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
for i := 0; i < 9; i += 3
Currently we compute bounds of [0,8]. Really we know that it is [0,6].
CL 415874 computed the better bound as part of overflow detection.
This CL just incorporates that better info to the prove pass.
R=go1.20
Change-Id: Ife82cc415321f6652c2b5d132a40ec23e3385766
Reviewed-on: https://go-review.googlesource.com/c/go/+/415937
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
The prove pass will mark some shifts bounded, and then we can use that
information to generate better code on riscv64.
Change-Id: Ia22f43d0598453c9417adac7017db28d7240948b
Reviewed-on: https://go-review.googlesource.com/c/go/+/422616
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Joel Sing <joel@sing.id.au>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
If x+delta cannot overflow/underflow, we can derive:
x+delta < x if delta<0 (this CL included)
x+delta > x if delta>0 (this CL not included due to
a recursive stack overflow)
Remove 95 bounds checks during ./make.bat
Fixes#51622
Change-Id: I60d9bd84c5d7e81bbf808508afd09be596644f09
Reviewed-on: https://go-review.googlesource.com/c/go/+/406175
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
CL 327871 changes methodWrapper to always perform inlining after global
escape analysis. However, inlining the method may reveal closures, which
require walking all function bodies to decide whether to capture free
variables by value or by ref.
To fix it, just not doing inline if the method contains any closures.
Fixes#53702
Change-Id: I4b0255b86257cc6fe7e5fafbc545cc5cff9113e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/426334
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Shape-based stenciling in unified IR is done by converting type argument
to its underlying type. So it agressively check that type argument is
not a TFORW. However, for recursive instantiated type argument, it may
still be a TFORW when shapifying happens. Thus the assertion failed,
causing the compiler crashing.
To fix it, just allow fully instantiated type when shapifying.
Fixes#54512Fixes#54722
Change-Id: I527e3fd696388c8a37454e738f0324f0c2ec16cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/426335
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
In typebits.Set we check that the offset is a multiple of the
alignment, which makes perfect sense. But for values like
atomic.Int64, which has 8-byte alignment even on 32-bit platforms
(i.e. the alignment is larger than PtrSize), if it is on stack it
may be under-aligned, as the stack frame is only PtrSize aligned.
Normally we would prevent such values on stack, as the escape
analysis force values with higher alignment to heap. But for a
composite literal assignment like x = AlignedType{...}, the
compiler creates an autotmp for the RHS then copies it to the LHS.
The autotmp is on stack and may be under-aligned. Currently this
may cause an ICE in the typebits.Set check.
This CL makes it align the _offset_ of the autotmp to 8 bytes,
which satisfies the check. Note that this is actually lying: the
actual address at run time may not necessarily be 8-byte
aligned as we only align SP to 4 bytes.
The under-alignment is probably okay. The only purpose for the
autotmp is to copy the value to the LHS, and the copying code we
generate (at least currently) doesn't care the alignment beyond
stack alignment.
Fixes#54638.
Change-Id: I13c16afde2eea017479ff11dfc24092bcb8aba6a
Reviewed-on: https://go-review.googlesource.com/c/go/+/425256
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
When inlining function calls, we rewrite the position information on
all of the nodes to keep track of the inlining context. This is
necessary so that at runtime, we can synthesize additional stack
frames so that the inlining is transparent to the user.
However, for function literals, we *don't* want to apply this
rewriting to the underlying function. Because within the function
literal (when it's not itself inlined), the inlining context (if any)
will have already be available at the caller PC instead.
Unified IR was already getting this right in the case of user-written
statements within the function literal, which is what the unit test
for #46234 tested. However, it was still using inline-adjusted
positions for the function declaration and its parameters, which
occasionally end up getting used for generated code (e.g., loading
captured values from the closure record).
I've manually verified that this fixes the hang in
https://go.dev/play/p/avQ0qgRzOgt, and spot-checked the
-d=pctab=pctoinline output for kube-apiserver and kubelet and they
seem better.
However, I'm still working on a more robust test for this (hence
"Updates" not "Fixes") and internal assertions to verify that we're
emitting correct inline trees. In particular, there are still other
cases (even in the non-unified frontend) where we're producing
corrupt (but at least acyclic) inline trees.
Updates #54625.
Change-Id: Iacfd2e1eb06ae8dc299c0679f377461d3d46c15a
Reviewed-on: https://go-review.googlesource.com/c/go/+/425395
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This is a follow up of CL 425101 on RISCV64.
According to RISCV Volume 1, Unprivileged Spec v. 20191213 Chapter 7.1:
If both the high and low bits of the same product are required, then the
recommended code sequence is: MULH[[S]U] rdh, rs1, rs2; MUL rdl, rs1, rs2
(source register specifiers must be in same order and rdh cannot be the
same as rs1 or rs2). Microarchitectures can then fuse these into a single
multiply operation instead of performing two separate multiplies.
So we should not split Muluhilo to separate instructions.
Updates #54607
Change-Id: If47461f3aaaf00e27cd583a9990e144fb8bcdb17
Reviewed-on: https://go-review.googlesource.com/c/go/+/425203
Auto-Submit: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Wayne Zuo <wdvxdr@golangcn.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This CL changes the inliner to process transitive inlining iteratively
after the AST has actually been edited, rather than recursively and
immediately. This is important for handling indirect function calls
correctly, because ir.reassigned walks the function body looking for
reassignments; whereas previously the inlined reassignments might not
have been actually added to the AST yet.
Fixes#54632.
Change-Id: I0dd69813c8a70b965174e0072335bc00afedf286
Reviewed-on: https://go-review.googlesource.com/c/go/+/425257
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Detect rotate instructions while still in architecture-independent form.
It's easier to do here, and we don't need to repeat it in each
architecture file.
Change-Id: I9396954b3f3b3bfb96c160d064a02002309935bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/421195
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Eric Fang <eric.fang@arm.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
Reviewed-by: Ruinan Sun <Ruinan.Sun@arm.com>
Run-TryBot: Keith Randall <khr@golang.org>
Normally, when moving Go values of type T from one location to another,
we don't need to worry about partial overlaps. The two Ts must either be
in disjoint (nonoverlapping) memory or in exactly the same location.
There are 2 cases where this isn't true:
1) Using unsafe you can arrange partial overlaps.
2) Since Go 1.17, you can use a cast from a slice to a ptr-to-array.
https://go.dev/ref/spec#Conversions_from_slice_to_array_pointer
This feature can be used to construct partial overlaps of array types.
var a [3]int
p := (*[2]int)(a[:])
q := (*[2]int)(a[1:])
*p = *q
We don't care about solving 1. Or at least, we haven't historically
and no one has complained.
For 2, we need to ensure that if there might be partial overlap,
then we can't use OpMove; we must use memmove instead.
(memmove handles partial overlap by copying in the correct
direction. OpMove does not.)
Note that we have to be careful here not to introduce a call when
we're marshaling arguments to a call or unmarshaling results from a call.
Fixes#54467
Change-Id: I1ca6aba8041576849c1d85f1fa33ae61b80a373d
Reviewed-on: https://go-review.googlesource.com/c/go/+/425076
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
This reverts CL 424854.
Reason for revert: broke misc/cgo/stdio.TestTestRun on several builders.
Will re-land after CL 421879 is submitted.
Change-Id: I2548c70d33d7c178cc71c1d491cd81c22660348f
Reviewed-on: https://go-review.googlesource.com/c/go/+/425214
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
In CL 424734, I implemented pointer shaping for unified IR. Evidently
though, we didn't have any test cases that check that uses of
pointer-shaped expressions were handled correctly.
In the reported test case, the struct field "children items[*node[T]]"
gets shaped to "children items[go.shape.*uint8]" (underlying type
"[]go.shape.*uint8"); and so the expression "n.children[i]" has type
"go.shape.*uint8" and the ".items" field selection expression fails.
The fix implemented in this CL is that any expression of derived type
now gets an explicit "reshape" operation applied to it, to ensure it
has the appropriate type for its context. E.g., the "n.children[i]"
OINDEX expression above gets "reshaped" from "go.shape.*uint8" to
"*node[go.shape.int]", allowing the field selection to succeed.
This CL also adds a "-d=reshape" compiler debugging flag, because I
anticipate debugging reshaping operations will be something to come up
again in the future.
Fixes#54535.
Change-Id: Id847bd8f51300d2491d679505ee4d2e974ca972a
Reviewed-on: https://go-review.googlesource.com/c/go/+/424936
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: hopehook <hopehook@qq.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
During walk, we sometimes desugar OEQ nodes into multiple "untyped
bool" expressions, and then use typecheck.Conv to convert back to the
original OEQ node's type.
However, typecheck.Conv had a short-circuit path that if the type is
already identical to the target type according to types.Identical,
then we skipped the conversion. This short-circuit is normally fine;
but with generic code and shape types, it considers "untyped bool" and
"go.shape.bool" to be identical types. And we could end up leaving an
expression of "untyped bool", which then fails an internal consistency
check later.
The simple fix is to change Conv to use types.IdenticalStrict, so that
we ensure "untyped bool" gets converted to "go.shape.bool". And for
good measure, make the same change to ConvNop.
This issue was discovered and reported against unified IR, but the
issue was latent within the non-unified frontend too.
Fixes#54537.
Change-Id: I7559a346b063349b35749e8a2da704be18e51654
Reviewed-on: https://go-review.googlesource.com/c/go/+/424937
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
To disambiguate local types, we append a "·N" suffix to their name and
then trim it off again when producing their runtime type descriptors.
However, if a local type is generic, then we were further appending
the type arguments after this suffix, and the code in types/fmt.go
responsible for trimming didn't know to handle this.
We could extend the types/fmt.go code to look for the "·N" suffix
elsewhere in the type name, but this is risky because it could
legitimately (albeit unlikely) appear in struct field tags.
Instead, the most robust solution is to just change the mangling logic
to keep the "·N" suffix at the end, where types/fmt.go can easily and
reliably trim it.
Note: the "·N" suffix is still visible within the type arguments
list (e.g., the "·3" suffixes in nested.out), because we currently use
the link strings in the type arguments list.
Fixes#54456.
Change-Id: Ie9beaf7e5330982f539bff57b8d48868a3674a37
Reviewed-on: https://go-review.googlesource.com/c/go/+/424901
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Than McIntosh <thanm@google.com>
When handling a type declaration like:
```
type B A
```
unified IR has been writing out that B's underlying type is A, rather
than the underlying type of A.
This is a bit awkward to implement and adds complexity to importers,
who need to handle resolving the underlying type themselves. But it
was necessary to handle when A was declared like:
```
//go:notinheap
type A int
```
Because we expected A's not-in-heap'ness to be conferred to B, which
required knowing that A was on the path from B to its actual
underlying type int.
However, since #46731 was accepted, we no longer need to support this
case. Instead we can write out B's actual underlying type.
One stumbling point though is the existing code for exporting
interfaces doesn't work for the underlying type of `comparable`, which
is now needed to implement `type C comparable`. As a bit of a hack, we
we instead export its underlying type as `interface{ comparable }`.
Fixes#54512.
Change-Id: I0fb892068d656f1e87bb8ef97da27756051126d5
Reviewed-on: https://go-review.googlesource.com/c/go/+/424854
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Previously we convert $0 to the ZR register for some reasons, which causes
two problems:
1. Confusion, the special case of the ZR register needs to be considered
when dealing with constants. For encoding, some places we encode ZR, and
some places we encode $0, although we have converted $0 to ZR.
2. Unexpected instruction format. All instructions that support ZR register
operands can be replaced by $0.
This patch removes this conversion. Note that this patch may cause previously
unintendedly supported instruction formats to no longer be supported.
Change-Id: I3d8d2c06711b7614a38191397da7776417f1861c
Reviewed-on: https://go-review.googlesource.com/c/go/+/404316
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Eric Fang <eric.fang@arm.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
On ARM64 we use two separate instructions to compute the hi and lo
results of a 64x64->128 multiplication. Lower to two separate ops
so if only one result is needed we can deadcode the other.
Fixes#54607.
Change-Id: Ib023e77eb2b2b0bcf467b45471cb8a294bce6f90
Reviewed-on: https://go-review.googlesource.com/c/go/+/425101
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
For #23870
Change-Id: I3bbe0f751254d1354a59a88b45e6f944c7a2fb4d
Reviewed-on: https://go-review.googlesource.com/c/go/+/417874
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
With the introduction of stack objects, VARKILL information is
no longer needed.
With stack objects, an object is dead when there are no more static
references to it, and the stack scanner can't find any live pointers
to it. VARKILL information isn't used to establish live ranges for
address-taken variables any more. In effect, the last static reference
*is* the VARKILL, and there's an additional dynamic liveness check
during stack scanning.
Next CL will actually rip out the VARKILL opcodes.
Change-Id: I030a2ab867445cf4e0e69397911f8a2e2f0ed07b
Reviewed-on: https://go-review.googlesource.com/c/go/+/419234
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
We don't need this special loop construct anymore now that we do
conservative GC scanning of the top of stack. Rewrite instead to a simple
pointer increment on every iteration. This leads to having a potential
past-the-end pointer at the end of the last iteration, but that value
immediately goes dead after the loop condition fails, and the past-the-end
pointer is never live across any call.
This simplifies and speeds up loops.
R=go1.20
TODO: actually delete all support for OFORUNTIL. It is now never generated,
but code to handle it (e.g. in ssagen) is still around.
TODO: in "for _, x := range" loops, we could get rid of the index
altogether and use a "pointer to the last element" reference to determine
when the loop is complete.
Fixes#53409
Change-Id: Ifc141600ff898a8bc6a75f793e575f8862679ba1
Reviewed-on: https://go-review.googlesource.com/c/go/+/414876
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
The non-unified frontend had repeated issues with inlining and
generics (#49309, #51909, #52907), which led us to substantially
restrict inlining when shape types were present.
However, these issues are evidently not present in unified IR's
inliner, and the safety restrictions added for the non-unified
frontend can simply be disabled in unified mode.
Fixes#54497.
Change-Id: I8e6ac9f3393c588bfaf14c6452891b9640a9d1bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/424775
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
As a consistency check in devirtualization, when we determine `i` (of
interface type `I`) always has dynamic type `T`, we insert a type
assertion `i.(T)`. This emits an itab check for `go:itab.T,I`, but
it's always true (and so SSA optimizes it away).
However, if `I` is instead the generic interface type `I[T]`, then
`go:itab.T,I[int]` and `go:itab.T,I[go.shape.int]` are equivalent but
distinct itabs. And notably, we'll have originally created the
interface value using the former; but the (non-dynamic) TypeAssertExpr
created by devirtualization would ultimately emit a comparison against
the latter. This comparison would then evaluate false, leading to a
spurious type assertion panic at runtime.
The comparison is just meant as an extra safety check, so it should be
safe to just disable. But for now, it's simpler/safer to just punt on
devirtualization in this case. (The non-unified frontend doesn't
devirtualize this either.)
Change-Id: I6a8809bcfebc9571f32e289fa4bc6a8b0d21ca46
Reviewed-on: https://go-review.googlesource.com/c/go/+/424774
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This CL switches unified IR to use shape-based stenciling with runtime
dictionaries, like the existing non-unified frontend. Specifically,
when instantiating generic functions and types `X[T]`, we now also
instantiated shaped variants `X[shapify(T)]` that can be shared by
`T`'s with common underlying types.
For example, for generic function `F`, `F[int](args...)` will be
rewritten to `F[go.shape.int](&.dict.F[int], args...)`.
For generic type `T` with method `M` and value `t` of type `T[int]`,
`t.M(args...)` will be rewritten to `T[go.shape.int].M(t,
&.dict.T[int], args...)`.
Two notable distinctions from the non-unified frontend:
1. For simplicity, currently shaping is limited to simply converting
type arguments to their underlying type. Subsequent CLs will implement
more aggressive shaping.
2. For generic types, a single dictionary is generated to be shared by
all methods, rather than separate dictionaries for each method. I
originally went with this design because I have an idea of changing
interface calls to pass the itab pointer via the closure
register (which should have zero overhead), and then the interface
wrappers for generic methods could use the *runtime.itab to find the
runtime dictionary that corresponds to the dynamic type. This would
allow emitting fewer method wrappers.
However, this choice does have the consequence that currently even if
a method is unused and its code is pruned by the linker, it may have
produced runtime dictionary entries that need to be kept alive anyway.
I'm open to changing this to generate per-method dictionaries, though
this would require changing the unified IR export data format; so it
would be best to make this decision before Go 1.20.
The other option is making the linker smarter about pruning unneeded
dictionary entries, like how it already prunes itab entries. For
example, the runtime dictionary for `T[int]` could have a `R_DICTTYPE`
meta-relocation against symbol `.dicttype.T[go.shape.int]` that
declares it's a dictionary associated with that type; and then each
method on `T[go.shape.T]` could have `R_DICTUSE` meta-relocations
against `.dicttype.T[go.shape.T]+offset` indicating which fields
within dictionaries of that type need to be preserved.
Change-Id: I369580b1d93d19640a4b5ecada4f6231adcce3fd
Reviewed-on: https://go-review.googlesource.com/c/go/+/421821
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Updated multiple tests in test/codegen: math.go, mathbits.go, shift.go
and slices.go to verify on ppc64/ppc64le as well
Change-Id: Id88dd41569b7097819fb4d451b615f69cf7f7a94
Reviewed-on: https://go-review.googlesource.com/c/go/+/412115
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Archana Ravindar <aravind5@in.ibm.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Paul Murphy <murp@ibm.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
CL 414836 limited the check for implicit dot for method call enabled by
a type bound. However, the checking condition for ODOTMETH only is not
right. For example, for promoted method, we have a OXDOT node instead,
and we still have to check for implicit dot in this case.
However, if the base type and embedded types have the same method name,
e.g in issue #53419, typecheck.AddImplicitDots will be confused and
result in an ambigus selector.
To fix this, we ensure methods for the base type are computed, then only
do the implicit dot check if we can find a matched method.
Fixes#54348
Change-Id: Iefe84ff330830afe35c5daffd499824db108da23
Reviewed-on: https://go-review.googlesource.com/c/go/+/422274
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>