]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: remove special escape analysis tags
authorMatthew Dempsky <mdempsky@google.com>
Tue, 22 Jun 2021 05:03:02 +0000 (22:03 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 22 Jun 2021 09:11:39 +0000 (09:11 +0000)
This CL removes the special escape analysis tags added to support
//go:uintptrescapes and calls to external functions. Instead, these
are kept as function pragmas.

This CL by itself isn't very interesting, but I expect will help with
subsequent cleanups I have planned here.

Change-Id: Ifb960289a27e0a6295ce2d2f5ec233cac590522b
Reviewed-on: https://go-review.googlesource.com/c/go/+/329969
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/escape/escape.go
src/cmd/compile/internal/ir/node.go
src/cmd/compile/internal/walk/order.go

index e3727bca27ce286d08b694c3b5b6b733fbb3ce0a..3a937518eccf37e61f4a65b0b8ac438cb4cd5ef7 100644 (file)
@@ -1132,7 +1132,7 @@ func (e *escape) tagHole(ks []hole, fn *ir.Name, param *types.Field) hole {
 
        // Call to previously tagged function.
 
-       if param.Note == UintptrEscapesNote {
+       if fn.Func != nil && fn.Func.Pragma&ir.UintptrEscapes != 0 && (param.Type.IsUintptr() || param.IsDDD() && param.Type.Elem().IsUintptr()) {
                k := e.heapHole()
                k.uintptrEscapesHack = true
                return k
@@ -2048,15 +2048,6 @@ func HeapAllocReason(n ir.Node) string {
        return ""
 }
 
-// This special tag is applied to uintptr variables
-// that we believe may hold unsafe.Pointers for
-// calls into assembly functions.
-const UnsafeUintptrNote = "unsafe-uintptr"
-
-// This special tag is applied to uintptr parameters of functions
-// marked go:uintptrescapes.
-const UintptrEscapesNote = "uintptr-escapes"
-
 func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
        name := func() string {
                if f.Sym != nil {
@@ -2072,11 +2063,13 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
                // This really doesn't have much to do with escape analysis per se,
                // but we are reusing the ability to annotate an individual function
                // argument and pass those annotations along to importing code.
+               fn.Pragma |= ir.UintptrKeepAlive
+
                if f.Type.IsUintptr() {
                        if base.Flag.LowerM != 0 {
                                base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
                        }
-                       return UnsafeUintptrNote
+                       return ""
                }
 
                if !f.Type.HasPointers() { // don't bother tagging for scalars
@@ -2102,18 +2095,20 @@ func (b *batch) paramTag(fn *ir.Func, narg int, f *types.Field) string {
        }
 
        if fn.Pragma&ir.UintptrEscapes != 0 {
+               fn.Pragma |= ir.UintptrKeepAlive
+
                if f.Type.IsUintptr() {
                        if base.Flag.LowerM != 0 {
                                base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
                        }
-                       return UintptrEscapesNote
+                       return ""
                }
                if f.IsDDD() && f.Type.Elem().IsUintptr() {
                        // final argument is ...uintptr.
                        if base.Flag.LowerM != 0 {
                                base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
                        }
-                       return UintptrEscapesNote
+                       return ""
                }
        }
 
index 9191eeb1d6cda6f5b3aaf1f25d9325c4bcc4fe48..7c3dc10e46df03b0b8b6c3322d9b644383152080 100644 (file)
@@ -436,18 +436,19 @@ func (s NameSet) Sorted(less func(*Name, *Name) bool) []*Name {
        return res
 }
 
-type PragmaFlag int16
+type PragmaFlag uint16
 
 const (
        // Func pragmas.
-       Nointerface    PragmaFlag = 1 << iota
-       Noescape                  // func parameters don't escape
-       Norace                    // func must not have race detector annotations
-       Nosplit                   // func should not execute on separate stack
-       Noinline                  // func should not be inlined
-       NoCheckPtr                // func should not be instrumented by checkptr
-       CgoUnsafeArgs             // treat a pointer to one arg as a pointer to them all
-       UintptrEscapes            // pointers converted to uintptr escape
+       Nointerface      PragmaFlag = 1 << iota
+       Noescape                    // func parameters don't escape
+       Norace                      // func must not have race detector annotations
+       Nosplit                     // func should not execute on separate stack
+       Noinline                    // func should not be inlined
+       NoCheckPtr                  // func should not be instrumented by checkptr
+       CgoUnsafeArgs               // treat a pointer to one arg as a pointer to them all
+       UintptrKeepAlive            // pointers converted to uintptr must be kept alive (compiler internal only)
+       UintptrEscapes              // pointers converted to uintptr escape
 
        // Runtime-only func pragmas.
        // See ../../../../runtime/README.md for detailed descriptions.
index 845bf036571aa137073756cf41218fe3ce0fb3bb..b9aff032404ea8850c96ceaabf756ae769eb588d 100644 (file)
@@ -9,7 +9,6 @@ import (
        "go/constant"
 
        "cmd/compile/internal/base"
-       "cmd/compile/internal/escape"
        "cmd/compile/internal/ir"
        "cmd/compile/internal/reflectdata"
        "cmd/compile/internal/staticinit"
@@ -554,37 +553,46 @@ func (o *orderState) call(nn ir.Node) {
        n.X = o.expr(n.X, nil)
        o.exprList(n.Args)
 
-       if n.Op() == ir.OCALLINTER {
+       // Pick out the function callee, if statically known.
+       // TODO(mdempsky): De-duplicate with similar code in escape analysis.
+       var callee *ir.Func
+       switch n.Op() {
+       case ir.OCALLFUNC:
+               if fn, ok := n.X.(*ir.Name); ok && fn.Op() == ir.ONAME && fn.Class == ir.PFUNC {
+                       callee = fn.Func
+               }
+       case ir.OCALLMETH:
+               callee = ir.MethodExprName(n.X).Func
+       }
+
+       if callee == nil || callee.Pragma&ir.UintptrKeepAlive == 0 {
                return
        }
-       keepAlive := func(arg ir.Node) {
+
+       keepAlive := func(args []ir.Node) {
                // If the argument is really a pointer being converted to uintptr,
                // arrange for the pointer to be kept alive until the call returns,
                // by copying it into a temp and marking that temp
                // still alive when we pop the temp stack.
-               if arg.Op() == ir.OCONVNOP {
-                       arg := arg.(*ir.ConvExpr)
-                       if arg.X.Type().IsUnsafePtr() {
-                               x := o.copyExpr(arg.X)
-                               arg.X = x
-                               x.SetAddrtaken(true) // ensure SSA keeps the x variable
-                               n.KeepAlive = append(n.KeepAlive, x)
+               for _, arg := range args {
+                       if arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() {
+                               arg := arg.(*ir.ConvExpr)
+                               if arg.X.Type().IsUnsafePtr() {
+                                       x := o.copyExpr(arg.X)
+                                       arg.X = x
+                                       x.SetAddrtaken(true) // ensure SSA keeps the x variable
+                                       n.KeepAlive = append(n.KeepAlive, x)
+                               }
                        }
                }
        }
 
-       // Check for "unsafe-uintptr" tag provided by escape analysis.
-       for i, param := range n.X.Type().Params().FieldSlice() {
-               if param.Note == escape.UnsafeUintptrNote || param.Note == escape.UintptrEscapesNote {
-                       if arg := n.Args[i]; arg.Op() == ir.OSLICELIT {
-                               arg := arg.(*ir.CompLitExpr)
-                               for _, elt := range arg.List {
-                                       keepAlive(elt)
-                               }
-                       } else {
-                               keepAlive(arg)
-                       }
-               }
+       last := len(n.Args) - 1
+       if n.IsDDD && n.Args[last].Op() == ir.OSLICELIT {
+               keepAlive(n.Args[:last])
+               keepAlive(n.Args[last].(*ir.CompLitExpr).List)
+       } else {
+               keepAlive(n.Args)
        }
 }