Skip to content

Commit

Permalink
cmd/compile: interleave devirtualization and inlining
Browse files Browse the repository at this point in the history
This CL interleaves devirtualization and inlining, so that
devirtualized calls can be inlined.

Fixes golang#52193.

Change-Id: I681e7c55bdb90ebf6df315d334e7a58f05110d9c
Reviewed-on: https://go-review.googlesource.com/c/go/+/528321
Auto-Submit: Matthew Dempsky <[email protected]>
Reviewed-by: Than McIntosh <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
TryBot-Bypass: Matthew Dempsky <[email protected]>
  • Loading branch information
mdempsky authored and gopherbot committed Nov 20, 2023
1 parent ee6b347 commit 4a90cdb
Show file tree
Hide file tree
Showing 9 changed files with 265 additions and 207 deletions.
18 changes: 3 additions & 15 deletions src/cmd/compile/internal/devirtualize/devirtualize.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,9 @@ import (
"cmd/compile/internal/types"
)

// Static devirtualizes calls within fn where possible when the concrete callee
// StaticCall devirtualizes the given call if possible when the concrete callee
// is available statically.
func Static(fn *ir.Func) {
ir.CurFunc = fn

ir.VisitList(fn.Body, func(n ir.Node) {
switch n := n.(type) {
case *ir.CallExpr:
staticCall(n)
}
})
}

// staticCall devirtualizes the given call if possible when the concrete callee
// is available statically.
func staticCall(call *ir.CallExpr) {
func StaticCall(call *ir.CallExpr) {
// For promoted methods (including value-receiver methods promoted
// to pointer-receivers), the interface method wrapper may contain
// expressions that can panic (e.g., ODEREF, ODOTPTR,
Expand All @@ -51,6 +38,7 @@ func staticCall(call *ir.CallExpr) {
if call.Op() != ir.OCALLINTER {
return
}

sel := call.Fun.(*ir.SelectorExpr)
r := ir.StaticValue(sel.X)
if r.Op() != ir.OCONVIFACE {
Expand Down
25 changes: 5 additions & 20 deletions src/cmd/compile/internal/gc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"bytes"
"cmd/compile/internal/base"
"cmd/compile/internal/coverage"
"cmd/compile/internal/devirtualize"
"cmd/compile/internal/dwarfgen"
"cmd/compile/internal/escape"
"cmd/compile/internal/inline"
"cmd/compile/internal/inline/interleaved"
"cmd/compile/internal/ir"
"cmd/compile/internal/logopt"
"cmd/compile/internal/loopvar"
Expand Down Expand Up @@ -224,30 +224,15 @@ func Main(archInit func(*ssagen.ArchInfo)) {
}
}

base.Timer.Start("fe", "pgo-devirtualization")
if profile != nil && base.Debug.PGODevirtualize > 0 {
// TODO(prattmic): No need to use bottom-up visit order. This
// is mirroring the PGO IRGraph visit order, which also need
// not be bottom-up.
ir.VisitFuncsBottomUp(typecheck.Target.Funcs, func(list []*ir.Func, recursive bool) {
for _, fn := range list {
devirtualize.ProfileGuided(fn, profile)
}
})
ir.CurFunc = nil
}
// Interleaved devirtualization and inlining.
base.Timer.Start("fe", "devirtualize-and-inline")
interleaved.DevirtualizeAndInlinePackage(typecheck.Target, profile)

// Inlining
base.Timer.Start("fe", "inlining")
if base.Flag.LowerL != 0 {
inline.InlinePackage(profile)
}
noder.MakeWrappers(typecheck.Target) // must happen after inlining

// Devirtualize and get variable capture right in for loops
// Get variable capture right in for loops.
var transformed []loopvar.VarAndLoop
for _, fn := range typecheck.Target.Funcs {
devirtualize.Static(fn)
transformed = append(transformed, loopvar.ForCapture(fn)...)
}
ir.CurFunc = nil
Expand Down
Loading

0 comments on commit 4a90cdb

Please sign in to comment.