aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/devirtualize
AgeCommit message (Collapse)Author
2026-03-30cmd/compile/internal/devirtualize: improve debug logsMateusz Poliwczak
Change-Id: Ie8d74d0968c3dfa6fe3454f1d3fdf13d6a6a6944 Reviewed-on: https://go-review.googlesource.com/c/go/+/760162 Auto-Submit: Mateusz Poliwczak <mpoliwczak34@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2026-03-30cmd/compile/internal/devirtualize: use pointer identity for type comparisonMateusz Poliwczak
Fixes #78404 Change-Id: I6adc1fb42ad6a3acce21333c6819d0796a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/760161 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Keith Randall <khr@golang.org>
2025-11-21cmd/compile/internal/devirtualize: fix typosJes Cok
Change-Id: I4f5a89f452a252018072d067da4cdb9a6cb0f4fe GitHub-Last-Rev: 7eb108d3878109ccb9846d97b2adc7ea3003772a GitHub-Pull-Request: golang/go#76396 Reviewed-on: https://go-review.googlesource.com/c/go/+/722860 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Robert Griesemer <gri@google.com>
2025-10-14cmd/compile/internal/devirtualize: do not track assignments to non-PAUTOMateusz Poliwczak
We do not lookup/devirtualize such, so we can skip tracking them. Change-Id: I8bdb0b11c694e4b2326c236093508a356a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/711160 Reviewed-by: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
2025-10-14cmd/compile/internal/devirtualize: use FatalfAt instead of Fatalf where possibleMateusz Poliwczak
Change-Id: I5e9e9c89336446720c3c21347969e4126a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/711140 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Keith Randall <khr@golang.org>
2025-10-14cmd/compile/internal/devirtualize: fix OCONVNOP assertionMateusz Poliwczak
Fixes #75863 Change-Id: I1e5a0f3880dcd5f820a5b6f4540c49b16a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/711141 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Lasse Folger <lassefolger@google.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-10-08cmd/compile/internal/devirtualize: improve concrete type analysisMateusz Poliwczak
This change improves the concrete type analysis in the devirtualizer, it not longer relies on ir.Reassigned, it now statically tries to determine the concrete type of an interface, even when assigned multiple times, following type assertions and iface conversions. Alternative to CL 649195 Updates #69521 Fixes #64824 Change-Id: Ib1656e19f3619ab2e1e6b2c78346cc320490b2af GitHub-Last-Rev: e8fa0b12f0a7b1d7ae00e5edb54ce04d1f702c09 GitHub-Pull-Request: golang/go#71935 Reviewed-on: https://go-review.googlesource.com/c/go/+/652036 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org>
2025-04-02cmd/compile/internal/devirtualize: do not select a zero-weight edge as the ↵Julia Lapenko
hottest one When both a direct call and an interface call appear on the same line, PGO devirtualization may make a suboptimal decision. In some cases, the directly called function becomes a candidate for devirtualization if no other relevant outgoing edges with non-zero weight exist for the caller's IRNode in the WeightedCG. The edge to this candidate is considered the hottest. Despite having zero weight, this edge still causes the interface call to be devirtualized. This CL prevents devirtualization when the weight of the hottest edge is 0. Fixes #72092 Change-Id: I06c0c5e080398d86f832e09244aceaa4aeb98721 Reviewed-on: https://go-review.googlesource.com/c/go/+/655475 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-09-17runtime: move getclosureptr to internal/runtime/sysMichael Pratt
Moving these intrinsics to a base package enables other internal/runtime packages to use them. There is no immediate need for getclosureptr outside of runtime, but it is moved for consistency with the other intrinsics. For #54766. Change-Id: Ia68b16a938c8cb84cb222469db28e3a83861be5d Reviewed-on: https://go-review.googlesource.com/c/go/+/613262 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-08-19all: remove duplicated words in commentsOleksandr Redko
Change-Id: Id991ec0826a4e2857f00330b4b7ff2b71907b789 Reviewed-on: https://go-review.googlesource.com/c/go/+/606615 Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Robert Griesemer <gri@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com>
2024-06-12cmd/compile/internal: add a PGO devirt post-lookup cleanup hookThan McIntosh
The PGO-based devirtualization helper pgoir.addIndirectEdges makes a series of calls into the unified IR reader to import functions that would not normally be imported but may be the target of a hot indirect call from the current package. This importing primarily targets at non-generic functions and methods, but as part of the process we can encounter types that have methods (including generic methods) whose bodies need to be read in. When the reader encounters an inlinable func of this sort, it may (depending on the context) decide not to read the body right away, but instead adds the func to a list ("todoBodies") to be read in later on in a more convenient context. In the bug in question, a hot method lookup takes place in pgoir.addIndirectEdges, and as part of the import process we wind up with a type T with method M that is in this partially created state, and in addition T gets added to the unified IR's list of types that may need method wrappers. During wrapper generation we create a new wrapper "(*T).M" whose body has a call to "T.M", then farther on down the pike during escape analysis we try to analyze the two functions; this causes a crash due to "T.M" being in partially constructed state. As a fix, add a new "PostLookupCleanup" hook (in the unified IR reader) that pgoir.addIndirectEdges can invoke that takes care of reading in the bodies of any functions that have been added to the "todoBodies" list. [Note: creating a test case for this problem is proving to be very tricky; a new test will be added in a subsequent patch]. Fixes #67746. Change-Id: Ibc47ee79e08a55421728d35341df80a865231cff Reviewed-on: https://go-review.googlesource.com/c/go/+/591075 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-20cmd/compile: add structs.HostLayoutDavid Chase
This is for the proposal, plus a few bug fixes that would/will be necessary when this is put into actual use. Fixes #66408. Updates #63131. Change-Id: I3a66e09d707dd579c59f155e7f53367f41214c30 Reviewed-on: https://go-review.googlesource.com/c/go/+/578355 Reviewed-by: Austin Clements <austin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: David Chase <drchase@google.com>
2024-03-27cmd/compile: rename cmd/compile/internal/pgo to cmd/compile/internal/pgoirMichael Pratt
This helps reduce confusion with cmd/internal/pgo, which performs compilation-independent analysis. pgoir associates that data with the IR from the current package compilation. For #58102. Change-Id: I9ef1c8bc41db466d3340f41f6d071b95c09566de Reviewed-on: https://go-review.googlesource.com/c/go/+/569338 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-03-27cmd/compile,cmd/preprofile: move logic to shared common packageMichael Pratt
The processing performed in cmd/preprofile is a simple version of the same initial processing performed by cmd/compile/internal/pgo. Refactor this processing into the new IR-independent cmd/internal/pgo package. Now cmd/preprofile and cmd/compile run the same code for initial processing of a pprof profile, guaranteeing that they always stay in sync. Since it is now trivial, this CL makes one change to the serialization format: the entries are ordered by weight. This allows us to avoid sorting ByWeight on deserialization. Impact on PGO parsing when compiling cmd/compile with PGO: * Without preprocessing: PGO parsing ~13.7% of CPU time * With preprocessing (unsorted): ~2.9% of CPU time (sorting ~1.7%) * With preprocessing (sorted): ~1.3% of CPU time The remaining 1.3% of CPU time approximately breaks down as: * ~0.5% parsing the preprocessed profile * ~0.7% building weighted IR call graph * ~0.5% walking function IR to find direct calls * ~0.2% performing lookups for indirect calls targets For #58102. Change-Id: Iaba425ea30b063ca195fb2f7b29342961c8a64c2 Reviewed-on: https://go-review.googlesource.com/c/go/+/569337 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Pratt <mpratt@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2024-02-06cmd/compile: add missing colon in debug logMichael Pratt
Change-Id: Id76f4688a2ac45c1616d5c03274eec5d2108e555 Reviewed-on: https://go-review.googlesource.com/c/go/+/562156 Auto-Submit: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
2023-11-20cmd/compile/internal/devirtualize: use CallExpr.GoDefer for PGOMatthew Dempsky
CL 543657 dedup'd the go/defer statement recognition between the inliner and static devirtualizer. This CL extends that for PGO-based devirtualization too. Change-Id: I998753132af1ef17329676f4e17515f16e0acb03 Reviewed-on: https://go-review.googlesource.com/c/go/+/543775 Auto-Submit: Matthew Dempsky <mdempsky@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2023-11-20cmd/compile: interleave devirtualization and inliningMatthew Dempsky
This CL interleaves devirtualization and inlining, so that devirtualized calls can be inlined. Fixes #52193. Change-Id: I681e7c55bdb90ebf6df315d334e7a58f05110d9c Reviewed-on: https://go-review.googlesource.com/c/go/+/528321 Auto-Submit: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Bypass: Matthew Dempsky <mdempsky@google.com>
2023-11-20src: a/an grammar fixesVille Skyttä
Change-Id: I179b50ae8e73677d4d408b83424afbbfe6aa17a1 GitHub-Last-Rev: 2e2d9c1e45556155d02db4df381b99f2d1bc5c0e GitHub-Pull-Request: golang/go#63478 Reviewed-on: https://go-review.googlesource.com/c/go/+/534015 Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-11-20cmd/compile/internal/ir: add CallExpr.GoDeferMatthew Dempsky
The devirtualizer and inliner both want to recognize call expressions that are part of a go or defer statement. This CL refactors them to use a single CallExpr.GoDefer flag, which gets set during normalization of go/defer statements during typecheck. While here, drop some OCALLMETH assertions. Typecheck has been responsible for desugaring them into OCALLFUNC for a while now, and ssagen will check this again for us later anyway. Change-Id: I3fc370f4417431aae97239313da6fe523f512a2e Reviewed-on: https://go-review.googlesource.com/c/go/+/543657 Reviewed-by: Than McIntosh <thanm@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-11-16cmd/compile: allow disable of PGO function value devirtualization with flagMichael Pratt
Extend the pgodevirtualize debug flag to distinguish interface and function devirtualization. Setting 1 keeps interface devirtualization enabled but disables function value devirtualization. For #64209. Change-Id: I33aa7eb95ca0bdb215256d8c7cc8f9dac53ae30e Reviewed-on: https://go-review.googlesource.com/c/go/+/543115 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-16cmd/compile: don't devirtualize calls to runtime.memhash_varlenMichael Pratt
runtime.memhash_varlen is defined as a normal function, but it is actually a closure. All references are generated by cmd/compile/internal/reflectdata.genhash, which creates a closure containing the size of the type, which memhash_varlen accesses with runtime.getclosureptr. Since this doesn't look like a normal closure, ir.Func.OClosure is not set, thus PGO function value devirtualization is willing to devirtualize it, generating a call that completely ignores the closure context. This causes memhash_varlen to either crash or generate incorrect results. Skip this function, which is the only caller of getclosureptr. Unfortunately there isn't a good way to detect these ineligible functions more generally. Fixes #64209. Change-Id: Ibf509406667c6d4e5d431f10e5b1d1f926ecd7dc Reviewed-on: https://go-review.googlesource.com/c/go/+/543195 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-13cmd/compile: initial function value devirtualizationMichael Pratt
Today, PGO-based devirtualization only applies to interface calls. This CL extends initial support to function values (i.e., function/closure pointers passed as arguments or stored in a struct). This CL is a minimal implementation with several limitations. * Export data lookup of function value callees not implemented (equivalent of CL 497175; done in CL 540258). * Callees must be standard static functions. Callees that are closures (requiring closure context) are not supported. For #61577. Change-Id: I7d328859035249e176294cd0d9885b2d08c853f6 Reviewed-on: https://go-review.googlesource.com/c/go/+/539699 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-02cmd/compile: fix unstable selection of hottest edgeMichael Pratt
When selecting the hottest edge to use for PGO-based devirtualization, edges are order by: 1. Edge weight 2. If weights are equal, prefer the edge with IR available in the package. 3. Otherwise, simply sort lexicographically. The existing logic for (2) is incomplete. If the hottest edge so far is missing IR, but the new edge has IR, then it works as expected and selects the new edge. But if the hottest edge so far has IR and the new edge is missing IR, we want to always keep the hottest edge so far, but this logic will fall through and use lexicographical ordering instead. Adjust the check to always make an explicit choice when IR availability differs. Change-Id: Ia7fcc286aa9a62ac209fd978cfce60463505f4cd Reviewed-on: https://go-review.googlesource.com/c/go/+/539475 Auto-Submit: Michael Pratt <mpratt@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-10-05cmd/compile/internal/ir: tweak a couple namesMatthew Dempsky
CallExpr.X -> CallExpr.Fun This consistent with go/ast and cmd/compile/internal/syntax. OPRINTN -> OPRINTLN This op represents the "println" builtin; might as well spell it the same way. Change-Id: Iead1b007776658c717879cf0997b3c48028428f4 Reviewed-on: https://go-review.googlesource.com/c/go/+/532795 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-09-19cmd/compile: add pgohash for debugging/bisecting PGO optimizationsCherry Mui
When a PGO build fails or produces incorrect program, it is often unclear what the problem is. Add pgo hash so we can bisect to individual optimization decisions, which often helps debugging. Related to #58153. Change-Id: I651ffd9c53bad60f2f28c8ec2a90a3f532982712 Reviewed-on: https://go-review.googlesource.com/c/go/+/528400 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2023-09-12cmd/compile/internal/devirtualize: sort equal weight CallStat.Hottest by nameMichael Pratt
When two callees have equal weight, we need to sort by another criteria to ensure that we get stable output. Note that this is only for the CallStat debug JSON output. The actual callee selection already does this secondary sort in findHotConcreteCallee. Change-Id: I0de105623c5ccc793ca6f5799ea25e57bc286722 Reviewed-on: https://go-review.googlesource.com/c/go/+/527796 Auto-Submit: Michael Pratt <mpratt@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-08-22cmd/compile/internal/types: overhaul and simplify APIMatthew Dempsky
This CL removes a lot of the redundant methods for accessing struct fields and signature parameters. In particular, users never have to write ".Slice()" or ".FieldSlice()" anymore; the exported APIs just do what you want. Further internal refactorings to follow. Change-Id: I45212f6772fe16aad39d0e68b82d71b0796e5639 Reviewed-on: https://go-review.googlesource.com/c/go/+/521295 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: Austin Clements <austin@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-08-21cmd/compile: do some TODOs about FatalfMatthew Dempsky
Separate CL in case I'm mistaken. Change-Id: I6b5fa0efb27a6b4fb4c133698bd7e2f01b4cccdb Reviewed-on: https://go-review.googlesource.com/c/go/+/521195 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-08-20cmd/compile/internal/typecheck: add selector helpersMatthew Dempsky
This CL refactors common patterns for constructing field and method selector expressions. Notably, XDotField and XDotMethod are now the only two functions where a SelecterExpr with OXDOT is constructed. Change-Id: I4c087225d8b295c4a6a92281ffcbcabafe2dc94d Reviewed-on: https://go-review.googlesource.com/c/go/+/520979 Auto-Submit: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2023-08-18cmd/compile: remove some uses of ir.CurFuncMatthew Dempsky
This CL updates several frontend passes to stop relying on ir.CurFunc (at least directly). Change-Id: I3c3529e81e27fb05d54a828f081f7c7efc31af67 Reviewed-on: https://go-review.googlesource.com/c/go/+/520606 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: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-08-18cmd/compile/internal/typecheck: replace Temp calls with TempAtMatthew Dempsky
Steps towards eliminating implicit dependencies on base.Pos and ir.CurFunc. Mechanical CL produced with gofmt -r. Change-Id: I070015513cb955cbe87f9a148d81db8c0d4b0dc5 Reviewed-on: https://go-review.googlesource.com/c/go/+/520605 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: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com>
2023-06-29cmd/{go,compile}: run gofmtThan McIntosh
Ran gofmt on a couple of Go source files that needed it. Change-Id: I0e9f78831f531a728b892a63c6e0c517d92b11a8 Reviewed-on: https://go-review.googlesource.com/c/go/+/507156 Run-TryBot: Than McIntosh <thanm@google.com> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2023-06-06cmd/compile: check method name in PGO devirtualizationCherry Mui
Currently, we devirtualize an interface call if the profile indicates a concrete callee is hot on the same line, and the concrete receiver implements the interface. But it is possible that (likely due to another call on the same line, or possibly a stale profile) the concrete call is to a different method. With the current AST construction we generate correct code, as we extract the method name from the interface call and use that to create the concrete call. But the devirtualization decision is based on an unrelated call in the profile. Check the method name when finding the hottest callee, so we won't use unrelated calls to different methods. Change-Id: I75c026997926f21bd6cc5266d3ffe99649a9b2d9 Reviewed-on: https://go-review.googlesource.com/c/go/+/500961 Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com>
2023-06-06cmd/compile: adjust PGO devirtualization diagnostic messageCherry Mui
Make it more consistent with the static devirtualization diagnostic message. Keep the print of concrete callee's method name, as it is clearer. Change-Id: Ibe9b40253eaff2c0071353a2b388177213488822 Reviewed-on: https://go-review.googlesource.com/c/go/+/500960 Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com>
2023-06-03cmd/compile/internal/devirtualize: devirtualize methods in other packages ↵thepudds
if current package has a concrete reference The new PGO-driven indirect call specialization from CL 492436 in theory should allow for devirtualization on methods in another package when those methods are directly referenced in the current package. However, inline.InlineImpossible was checking for a zero-length fn.Body and would cause devirtualization to fail with a debug log message like: "should not PGO devirtualize (*Speaker1).Speak: no function body" Previously, the logic in inline.InlineImpossible was only called on local functions, but with PGO-based devirtualization, it can now be called on imported functions, where inlinable imported functions will have a zero-length fn.Body but a non-nil fn.Inl. We update inline.InlineImpossible to handle imported functions by adding a call to typecheck.HaveInlineBody in the check that was previously failing. For the test, we need to have a hopefully temporary workaround of adding explicit references to the callees in another package for devirtualization to work. CL 497175 or similar should enable removing this workaround. Fixes #60561 Updates #59959 Change-Id: I48449b7d8b329d84151bd3b506b8093c262eb2a3 GitHub-Last-Rev: 2d53c55fd895ad8fefd25510a6e6969e89d54a6d GitHub-Pull-Request: golang/go#60565 Reviewed-on: https://go-review.googlesource.com/c/go/+/500155 Run-TryBot: thepudds <thepudds1460@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2023-05-22cmd/compile: enable PGO-driven call devirtualizationMichael Pratt
This CL is originally based on CL 484838 from rajbarik@uber.com. Add a new PGO-based devirtualize pass. This pass conditionally devirtualizes interface calls for the hottest callee. That is, it performs a transformation like: type Iface interface { Foo() } type Concrete struct{} func (Concrete) Foo() {} func foo(i Iface) { i.Foo() } to: func foo(i Iface) { if c, ok := i.(Concrete); ok { c.Foo() } else { i.Foo() } } The primary benefit of this transformation is enabling inlining of the direct calls. Today this change has no impact on the escape behavior, as the fallback interface always forces an escape. But improving escape analysis to take advantage of this is an area of potential work. This CL is the bare minimum of a devirtualization implementation. There are still numerous limitations: * Callees not directly referenced in the current package can be missed (even if they are in the transitive dependences). * Callees not in the transitive dependencies of the current package are missed. * Only interface method calls are supported, not other indirect function calls. * Multiple calls to compatible interfaces on the same line cannot be distinguished and will use the same callee target. * Callees that only partially implement an interface (they are embedded in another type that completes the interface) cannot be devirtualized. * Others, mentioned in TODOs. Fixes #59959 Change-Id: I8bedb516139695ee4069650b099d05957b7ce5ee Reviewed-on: https://go-review.googlesource.com/c/go/+/492436 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> Auto-Submit: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
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>