]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: use HaveInlineBody for unified IR
authorMatthew Dempsky <mdempsky@google.com>
Wed, 31 Aug 2022 20:48:06 +0000 (13:48 -0700)
committerGopher Robot <gobot@golang.org>
Wed, 31 Aug 2022 22:22:43 +0000 (22:22 +0000)
In go.dev/cl/419674 I added a mechanism to the inliner to allow
inlining to fail gracefully when a function body is missing, but I
missed we already have a mechanism for that: typecheck.HaveInlineBody.

This CL makes it overridable so that unified IR can plug in its
appropriate logic, like it does with the logic for building the
ir.InlinedCallExpr node.

While here, rename inline.NewInline to inline.InlineCall, because the
name "NewInline" is now a misnomer since we initialize it to oldInline
(now named oldInlineCall).

Change-Id: I4e65618d3725919f69e6f43cf409699d20fb797c
Reviewed-on: https://go-review.googlesource.com/c/go/+/427234
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/inline/inl.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/unified.go
src/cmd/compile/internal/typecheck/iimport.go

index b335b84d1930e0877c9e26f36977ca5ee8a54e50..817f2fd99950bec60da2da9ab112dfddcd252a3a 100644 (file)
@@ -689,9 +689,9 @@ var inlgen int
 // when producing output for debugging the compiler itself.
 var SSADumpInline = func(*ir.Func) {}
 
-// NewInline allows the inliner implementation to be overridden.
+// InlineCall allows the inliner implementation to be overridden.
 // If it returns nil, the function will not be inlined.
-var NewInline = oldInline
+var InlineCall = oldInlineCall
 
 // If n is a OCALLFUNC node, and fn is an ONAME node for a
 // function with an inlinable body, return an OINLCALL node that can replace n.
@@ -817,9 +817,9 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlCalls *[]*ir.Inlin
                fmt.Printf("%v: Before inlining: %+v\n", ir.Line(n), n)
        }
 
-       res := NewInline(n, fn, inlIndex)
+       res := InlineCall(n, fn, inlIndex)
        if res == nil {
-               return n
+               base.FatalfAt(n.Pos(), "inlining call to %v failed", fn)
        }
 
        if base.Flag.LowerM > 2 {
@@ -855,11 +855,11 @@ func CalleeEffects(init *ir.Nodes, callee ir.Node) {
        }
 }
 
-// oldInline creates an InlinedCallExpr to replace the given call
+// oldInlineCall creates an InlinedCallExpr to replace the given call
 // expression. fn is the callee function to be inlined. inlIndex is
 // the inlining tree position index, for use with src.NewInliningBase
 // when rewriting positions.
-func oldInline(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
+func oldInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
        if base.Debug.TypecheckInl == 0 {
                typecheck.ImportedBody(fn)
        }
index a34d5c924a097f632a4325c6f134ed7aef18679e..8270c403fe38404ca7e8ce758a8b726087a16b42 100644 (file)
@@ -3374,22 +3374,28 @@ func (r *reader) pkgObjs(target *ir.Package) []*ir.Name {
 
 // @@@ Inlining
 
+// unifiedHaveInlineBody reports whether we have the function body for
+// fn, so we can inline it.
+func unifiedHaveInlineBody(fn *ir.Func) bool {
+       if fn.Inl == nil {
+               return false
+       }
+
+       _, ok := bodyReaderFor(fn)
+       return ok
+}
+
 var inlgen = 0
 
-// InlineCall implements inline.NewInline by re-reading the function
+// unifiedInlineCall implements inline.NewInline by re-reading the function
 // body from its Unified IR export data.
-func InlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
+func unifiedInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExpr {
        // TODO(mdempsky): Turn callerfn into an explicit parameter.
        callerfn := ir.CurFunc
 
        pri, ok := bodyReaderFor(fn)
        if !ok {
-               // TODO(mdempsky): Reconsider this diagnostic's wording, if it's
-               // to be included in Go 1.20.
-               if base.Flag.LowerM != 0 {
-                       base.WarnfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
-               }
-               return nil
+               base.FatalfAt(call.Pos(), "cannot inline call to %v: missing inline body", fn)
        }
 
        if fn.Inl.Body == nil {
index 394336c02028d6dac81661e5e95e3558cb78843b..b8e4fe78d7e037bad117c381a5d77ccb0c22f4e3 100644 (file)
@@ -69,7 +69,8 @@ var localPkgReader *pkgReader
 // In other words, we have all the necessary information to build the generic IR form
 // (see writer.captureVars for an example).
 func unified(noders []*noder) {
-       inline.NewInline = InlineCall
+       inline.InlineCall = unifiedInlineCall
+       typecheck.HaveInlineBody = unifiedHaveInlineBody
 
        data := writePkgStub(noders)
 
index 85cac7af7970a4db53d9b76739d9102f7d92137d..a08f62b4146cd929eb9fd87a7e302985b8a24a5d 100644 (file)
@@ -83,17 +83,14 @@ func ImportBody(fn *ir.Func) {
 
 // HaveInlineBody reports whether we have fn's inline body available
 // for inlining.
-func HaveInlineBody(fn *ir.Func) bool {
+//
+// It's a function literal so that it can be overriden for
+// GOEXPERIMENT=unified.
+var HaveInlineBody = func(fn *ir.Func) bool {
        if fn.Inl == nil {
                return false
        }
 
-       // Unified IR is much more conservative about pruning unreachable
-       // methods (at the cost of increased build artifact size).
-       if base.Debug.Unified != 0 {
-               return true
-       }
-
        if fn.Inl.Body != nil {
                return true
        }