aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/devirtualize/devirtualize.go
AgeCommit message (Collapse)Author
2023-01-25cmd: remove GOEXPERIMENT=nounified knobMatthew Dempsky
This CL removes the GOEXPERIMENT=nounified knob, and any conditional statements that depend on that knob. Further CLs to remove unreachable code follow this one. Updates #57410. Change-Id: I39c147e1a83601c73f8316a001705778fee64a91 Reviewed-on: https://go-review.googlesource.com/c/go/+/458615 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2022-12-14cmd/compile: desugar OCALLMETH->OCALLFUNC within devirtualizationMatthew Dempsky
Devirtualization can turn OCALLINTER into OCALLMETH, but then we want to actually desugar into OCALLFUNC instead for later phases. Just needs a missing call to typecheck.FixMethodCall. Fixes #57309. Change-Id: I331fbd40804e1a370134ef17fa6dd501c0920ed3 Reviewed-on: https://go-review.googlesource.com/c/go/+/457715 Auto-Submit: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2022-09-06cmd/compile: do not devirtualize defer/go callsCuong Manh Le
For defer/go calls, the function/method value are evaluated immediately. So after devirtualizing, it may trigger a panic when implicitly deref a nil pointer receiver, causing the program behaves unexpectedly. It's safer to not devirtualizing defer/go calls at all. Fixes #52072 Change-Id: I562c2860e3e577b36387dc0a12ae5077bc0766bf Reviewed-on: https://go-review.googlesource.com/c/go/+/428495 Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2022-08-18cmd/compile: fix devirtualization bug with unified IRMatthew Dempsky
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>
2022-08-18cmd/compile/internal/noder: shape-based stenciling for unified IRMatthew Dempsky
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>
2020-12-25[dev.regabi] cmd/compile: cleanup devirtualization docsMatthew Dempsky
Change-Id: I8e319f55fad6e9ed857aa020a96f3a89ccaadcea Reviewed-on: https://go-review.googlesource.com/c/go/+/280213 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-12-25[dev.regabi] cmd/compile: new devirtualization pkg [generated]Matthew Dempsky
The devirtualization code was only in inl.go because it reused some of the same helper functions as inlining (notably staticValue), but that code all ended up in package ir instead anyway. Beyond that minor commonality, it's entirely separate from inlining. It's definitely on the small side, but consistent with the new micropass-as-a-package approach we're trying. [git-generate] cd src/cmd/compile/internal/inline rf ' mv Devirtualize Func mv devirtualizeCall Call mv Func Call devirtualize.go mv devirtualize.go cmd/compile/internal/devirtualize ' Change-Id: Iff7b9fe486856660a8107d5391c54b7e8d238706 Reviewed-on: https://go-review.googlesource.com/c/go/+/280212 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>