]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: emit unified IR wrappers after inlining
authorMatthew Dempsky <mdempsky@google.com>
Wed, 1 Sep 2021 18:53:36 +0000 (11:53 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 1 Sep 2021 21:38:43 +0000 (21:38 +0000)
This CL delays unified IR's wrapper generation to after inlining.

Change-Id: Idfe496663489d6b797a647eb17200c6322d0334a
Reviewed-on: https://go-review.googlesource.com/c/go/+/347029
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>
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/unified.go

index 0dbe47f6537e51cd45b97aa0e8007efb4b0f71ca..8ddef6721f601c3f7e42983f365ed62360588e50 100644 (file)
@@ -245,6 +245,7 @@ func Main(archInit func(*ssagen.ArchInfo)) {
        if base.Flag.LowerL != 0 {
                inline.InlinePackage()
        }
+       noder.MakeWrappers(typecheck.Target) // must happen after inlining
 
        // Devirtualize.
        for _, n := range typecheck.Target.Decls {
index e874240bbc4468ee26c445e9fb64d832737fbb74..17ccb25e1d9b142f598bb75305af5dc2822bbc30 100644 (file)
@@ -149,7 +149,7 @@ type readerDict struct {
        funcsObj []ir.Node
 }
 
-func (r *reader) setType(n ir.Node, typ *types.Type) {
+func setType(n ir.Node, typ *types.Type) {
        n.SetType(typ)
        n.SetTypecheck(1)
 
@@ -159,7 +159,7 @@ func (r *reader) setType(n ir.Node, typ *types.Type) {
        }
 }
 
-func (r *reader) setValue(name *ir.Name, val constant.Value) {
+func setValue(name *ir.Name, val constant.Value) {
        name.SetVal(val)
        name.Defn = nil
 }
@@ -602,15 +602,15 @@ func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node
 
        case objAlias:
                name := do(ir.OTYPE, false)
-               r.setType(name, r.typ())
+               setType(name, r.typ())
                name.SetAlias(true)
                return name
 
        case objConst:
                name := do(ir.OLITERAL, false)
                typ, val := r.value()
-               r.setType(name, typ)
-               r.setValue(name, val)
+               setType(name, typ)
+               setValue(name, val)
                return name
 
        case objFunc:
@@ -618,7 +618,7 @@ func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node
                        sym = renameinit()
                }
                name := do(ir.ONAME, true)
-               r.setType(name, r.signature(sym.Pkg, nil))
+               setType(name, r.signature(sym.Pkg, nil))
 
                name.Func = ir.NewFunc(r.pos())
                name.Func.Nname = name
@@ -629,7 +629,7 @@ func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node
        case objType:
                name := do(ir.OTYPE, true)
                typ := types.NewNamed(name)
-               r.setType(name, typ)
+               setType(name, typ)
 
                // Important: We need to do this before SetUnderlying.
                r.ext.typeExt(name)
@@ -654,7 +654,7 @@ func (pr *pkgReader) objIdx(idx int, implicits, explicits []*types.Type) ir.Node
 
        case objVar:
                name := do(ir.ONAME, false)
-               r.setType(name, r.typ())
+               setType(name, r.typ())
                r.ext.varExt(name)
                return name
        }
@@ -754,7 +754,7 @@ func (r *reader) method() *types.Field {
        fnsym := sym
        fnsym = ir.MethodSym(recv.Type, fnsym)
        name := ir.NewNameAt(pos, fnsym)
-       r.setType(name, typ)
+       setType(name, typ)
 
        name.Func = ir.NewFunc(r.pos())
        name.Func.Nname = name
@@ -996,7 +996,7 @@ func (r *reader) funcarg(param *types.Field, sym *types.Sym, ctxt ir.Class) {
        }
 
        name := ir.NewNameAt(r.updatePos(param.Pos), sym)
-       r.setType(name, param.Type)
+       setType(name, param.Type)
        r.addLocal(name, ctxt)
 
        if r.inlCall == nil {
@@ -1276,7 +1276,7 @@ func (r *reader) stmt1(tag codeStmt, out *ir.Nodes) ir.Node {
 
                name := ir.NewDeclNameAt(src.NoXPos, ir.OTYPE, ir.BlankNode.Sym())
                name.SetAlias(true)
-               r.setType(name, types.Types[types.TINT])
+               setType(name, types.Types[types.TINT])
 
                n := ir.NewDecl(src.NoXPos, ir.ODCLTYPE, name)
                n.SetTypecheck(1)
@@ -1297,7 +1297,7 @@ func (r *reader) assignList() ([]*ir.Name, []ir.Node) {
                        name := ir.NewNameAt(pos, sym)
                        lhs[i] = name
                        names = append(names, name)
-                       r.setType(name, typ)
+                       setType(name, typ)
                        r.addLocal(name, ir.PAUTO)
                        continue
                }
@@ -1438,7 +1438,7 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node {
                        typ := r.typ()
 
                        name := ir.NewNameAt(pos, tswitch.Tag.Sym())
-                       r.setType(name, typ)
+                       setType(name, typ)
                        r.addLocal(name, ir.PAUTO)
                        clause.Var = name
                        name.Defn = tswitch
@@ -1701,12 +1701,12 @@ func (r *reader) funcLit() ir.Node {
        clo := fn.OClosure
        ir.NameClosure(clo, r.curfn)
 
-       r.setType(fn.Nname, xtype2)
+       setType(fn.Nname, xtype2)
        if quirksMode() {
                fn.Nname.Ntype = ir.TypeNodeAt(typPos, xtype2)
        }
        typecheck.Func(fn)
-       r.setType(clo, fn.Type())
+       setType(clo, fn.Type())
 
        fn.ClosureVars = make([]*ir.Name, 0, r.len())
        for len(fn.ClosureVars) < cap(fn.ClosureVars) {
@@ -1910,7 +1910,7 @@ func InlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.InlinedCallExp
        tmpfn.Closgen = callerfn.Closgen
        defer func() { callerfn.Closgen = tmpfn.Closgen }()
 
-       r.setType(tmpfn.Nname, fn.Type())
+       setType(tmpfn.Nname, fn.Type())
        r.curfn = tmpfn
 
        r.inlCaller = callerfn
@@ -2098,7 +2098,7 @@ func expandInline(fn *ir.Func, pri pkgReaderIndex) {
 
        {
                r := pri.asReader(relocBody, syncFuncBody)
-               r.setType(tmpfn.Nname, fn.Type())
+               setType(tmpfn.Nname, fn.Type())
 
                // Don't change parameter's Sym/Nname fields.
                r.funarghack = true
@@ -2194,34 +2194,39 @@ func (r *reader) importedDef() bool {
        return r.p != localPkgReader && !r.hasTypeParams()
 }
 
-func (r *reader) wrapTypes(target *ir.Package) {
+func MakeWrappers(target *ir.Package) {
+       // Only unified IR in non-quirks mode emits its own wrappers.
+       if base.Debug.Unified == 0 || quirksMode() {
+               return
+       }
+
        // always generate a wrapper for error.Error (#29304)
-       r.needWrapper(types.ErrorType)
+       needWrapperTypes = append(needWrapperTypes, types.ErrorType)
 
        seen := make(map[string]*types.Type)
 
        for _, typ := range haveWrapperTypes {
-               r.wrapType(typ, target, seen, false)
+               wrapType(typ, target, seen, false)
        }
        haveWrapperTypes = nil
 
        for _, typ := range needWrapperTypes {
-               r.wrapType(typ, target, seen, true)
+               wrapType(typ, target, seen, true)
        }
        needWrapperTypes = nil
 
        for _, wrapper := range haveMethodValueWrappers {
-               r.methodValueWrapper(wrapper.rcvr, wrapper.method, target, false)
+               wrapMethodValue(wrapper.rcvr, wrapper.method, target, false)
        }
        haveMethodValueWrappers = nil
 
        for _, wrapper := range needMethodValueWrappers {
-               r.methodValueWrapper(wrapper.rcvr, wrapper.method, target, true)
+               wrapMethodValue(wrapper.rcvr, wrapper.method, target, true)
        }
        needMethodValueWrappers = nil
 }
 
-func (r *reader) wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) {
+func wrapType(typ *types.Type, target *ir.Package, seen map[string]*types.Type, needed bool) {
        key := typ.LinkString()
        if prev := seen[key]; prev != nil {
                if !types.Identical(typ, prev) {
@@ -2244,22 +2249,22 @@ func (r *reader) wrapType(typ *types.Type, target *ir.Package, seen map[string]*
                        base.FatalfAt(meth.Pos, "invalid method: %v", meth)
                }
 
-               r.methodWrapper(0, typ, meth, target)
+               methodWrapper(0, typ, meth, target)
 
                // For non-interface types, we also want *T wrappers.
                if !typ.IsInterface() {
-                       r.methodWrapper(1, typ, meth, target)
+                       methodWrapper(1, typ, meth, target)
 
                        // For not-in-heap types, *T is a scalar, not pointer shaped,
                        // so the interface wrappers use **T.
                        if typ.NotInHeap() {
-                               r.methodWrapper(2, typ, meth, target)
+                               methodWrapper(2, typ, meth, target)
                        }
                }
        }
 }
 
-func (r *reader) methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) {
+func methodWrapper(derefs int, tbase *types.Type, method *types.Field, target *ir.Package) {
        wrapper := tbase
        for i := 0; i < derefs; i++ {
                wrapper = types.NewPtr(wrapper)
@@ -2279,7 +2284,7 @@ func (r *reader) methodWrapper(derefs int, tbase *types.Type, method *types.Fiel
        // TODO(mdempsky): Use method.Pos instead?
        pos := base.AutogeneratedPos
 
-       fn := r.newWrapperFunc(pos, sym, wrapper, method)
+       fn := newWrapperFunc(pos, sym, wrapper, method)
 
        var recv ir.Node = fn.Nname.Type().Recv().Nname.(*ir.Name)
 
@@ -2299,10 +2304,10 @@ func (r *reader) methodWrapper(derefs int, tbase *types.Type, method *types.Fiel
 
        addTailCall(pos, fn, recv, method)
 
-       r.finishWrapperFunc(fn, target)
+       finishWrapperFunc(fn, target)
 }
 
-func (r *reader) methodValueWrapper(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) {
+func wrapMethodValue(recvType *types.Type, method *types.Field, target *ir.Package, needed bool) {
        sym := ir.MethodSymSuffix(recvType, method.Sym, "-fm")
        if sym.Uniq() {
                return
@@ -2312,7 +2317,7 @@ func (r *reader) methodValueWrapper(recvType *types.Type, method *types.Field, t
        // TODO(mdempsky): Use method.Pos instead?
        pos := base.AutogeneratedPos
 
-       fn := r.newWrapperFunc(pos, sym, nil, method)
+       fn := newWrapperFunc(pos, sym, nil, method)
        sym.Def = fn.Nname
 
        // Declare and initialize variable holding receiver.
@@ -2325,10 +2330,10 @@ func (r *reader) methodValueWrapper(recvType *types.Type, method *types.Field, t
 
        addTailCall(pos, fn, recv, method)
 
-       r.finishWrapperFunc(fn, target)
+       finishWrapperFunc(fn, target)
 }
 
-func (r *reader) newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
+func newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Type, method *types.Field) *ir.Func {
        fn := ir.NewFunc(pos)
        fn.SetDupok(true) // TODO(mdempsky): Leave unset for local, non-generic wrappers?
 
@@ -2339,14 +2344,14 @@ func (r *reader) newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Typ
        fn.Nname = name
 
        sig := newWrapperType(wrapper, method)
-       r.setType(name, sig)
+       setType(name, sig)
 
        // TODO(mdempsky): De-duplicate with similar logic in funcargs.
        defParams := func(class ir.Class, params *types.Type) {
                for _, param := range params.FieldSlice() {
                        name := ir.NewNameAt(param.Pos, param.Sym)
                        name.Class = class
-                       r.setType(name, param.Type)
+                       setType(name, param.Type)
 
                        name.Curfn = fn
                        fn.Dcl = append(fn.Dcl, name)
@@ -2362,13 +2367,17 @@ func (r *reader) newWrapperFunc(pos src.XPos, sym *types.Sym, wrapper *types.Typ
        return fn
 }
 
-func (r *reader) finishWrapperFunc(fn *ir.Func, target *ir.Package) {
+func finishWrapperFunc(fn *ir.Func, target *ir.Package) {
        typecheck.Func(fn)
 
        ir.WithFunc(fn, func() {
                typecheck.Stmts(fn.Body)
        })
 
+       // We generate wrappers after the global inlining pass,
+       // so we're responsible for applying inlining ourselves here.
+       inline.InlineCalls(fn)
+
        target.Decls = append(target.Decls, fn)
 }
 
index 9f80ca000de317e8ca1ec2b03f05afe92922f691..bf63608bf1a0e9f2deadd663b1aec72b0d973d96 100644 (file)
@@ -138,11 +138,6 @@ func unified(noders []*noder) {
        }
        todoBodies = nil
 
-       if !quirksMode() {
-               // TODO(mdempsky): Investigate generating wrappers in quirks mode too.
-               r.wrapTypes(target)
-       }
-
        // Check that nothing snuck past typechecking.
        for _, n := range target.Decls {
                if n.Typecheck() == 0 {