]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: move stack objects to liveness
authorMatthew Dempsky <mdempsky@google.com>
Mon, 18 Jan 2021 06:05:50 +0000 (22:05 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 18 Jan 2021 06:33:56 +0000 (06:33 +0000)
Calculating and emitting stack objects are essentially part of
liveness analysis, so move the code from ssagen to liveness. Allows
unexporting liveness.ShouldTrack.

Passes toolstash -cmp.

Change-Id: I88b5b2e75b8dfb46b8b03a2fa09a9236865cbf3e
Reviewed-on: https://go-review.googlesource.com/c/go/+/284413
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/compile/internal/liveness/plive.go
src/cmd/compile/internal/ssagen/ssa.go

index c70db6ed18468aa73c5d34f05bae76c5d6c947f3..53ae797fce18f1fe7007ebdf9336f010bdfd5574 100644 (file)
@@ -17,12 +17,14 @@ package liveness
 import (
        "crypto/md5"
        "fmt"
+       "sort"
        "strings"
 
        "cmd/compile/internal/base"
        "cmd/compile/internal/bitvec"
        "cmd/compile/internal/ir"
        "cmd/compile/internal/objw"
+       "cmd/compile/internal/reflectdata"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/typebits"
        "cmd/compile/internal/types"
@@ -174,13 +176,13 @@ type progeffectscache struct {
        initialized bool
 }
 
-// ShouldTrack reports whether the liveness analysis
+// shouldTrack reports whether the liveness analysis
 // should track the variable n.
 // We don't care about variables that have no pointers,
 // nor do we care about non-local variables,
 // nor do we care about empty structs (handled by the pointer check),
 // nor do we care about the fake PAUTOHEAP variables.
-func ShouldTrack(n *ir.Name) bool {
+func shouldTrack(n *ir.Name) bool {
        return (n.Class == ir.PAUTO && n.Esc() != ir.EscHeap || n.Class == ir.PPARAM || n.Class == ir.PPARAMOUT) && n.Type().HasPointers()
 }
 
@@ -189,7 +191,7 @@ func ShouldTrack(n *ir.Name) bool {
 func getvariables(fn *ir.Func) ([]*ir.Name, map[*ir.Name]int32) {
        var vars []*ir.Name
        for _, n := range fn.Dcl {
-               if ShouldTrack(n) {
+               if shouldTrack(n) {
                        vars = append(vars, n)
                }
        }
@@ -1179,9 +1181,54 @@ func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) Map
        p.To.Name = obj.NAME_EXTERN
        p.To.Sym = fninfo.GCLocals
 
+       if x := lv.emitStackObjects(); x != nil {
+               p := pp.Prog(obj.AFUNCDATA)
+               p.From.SetConst(objabi.FUNCDATA_StackObjects)
+               p.To.Type = obj.TYPE_MEM
+               p.To.Name = obj.NAME_EXTERN
+               p.To.Sym = x
+       }
+
        return lv.livenessMap
 }
 
+func (lv *liveness) emitStackObjects() *obj.LSym {
+       var vars []*ir.Name
+       for _, n := range lv.fn.Dcl {
+               if shouldTrack(n) && n.Addrtaken() && n.Esc() != ir.EscHeap {
+                       vars = append(vars, n)
+               }
+       }
+       if len(vars) == 0 {
+               return nil
+       }
+
+       // Sort variables from lowest to highest address.
+       sort.Slice(vars, func(i, j int) bool { return vars[i].FrameOffset() < vars[j].FrameOffset() })
+
+       // Populate the stack object data.
+       // Format must match runtime/stack.go:stackObjectRecord.
+       x := base.Ctxt.Lookup(lv.fn.LSym.Name + ".stkobj")
+       lv.fn.LSym.Func().StackObjects = x
+       off := 0
+       off = objw.Uintptr(x, off, uint64(len(vars)))
+       for _, v := range vars {
+               // Note: arguments and return values have non-negative Xoffset,
+               // in which case the offset is relative to argp.
+               // Locals have a negative Xoffset, in which case the offset is relative to varp.
+               off = objw.Uintptr(x, off, uint64(v.FrameOffset()))
+               off = objw.SymPtr(x, off, reflectdata.TypeLinksym(v.Type()), 0)
+       }
+
+       if base.Flag.Live != 0 {
+               for _, v := range vars {
+                       base.WarnfAt(v.Pos(), "stack object %v %v", v, v.Type())
+               }
+       }
+
+       return x
+}
+
 // isfat reports whether a variable of type t needs multiple assignments to initialize.
 // For example:
 //
index 02aff7a8cf1fc6f3baa6941d18c35f8f7e2f04ec..0a1a7aed8481c332f6232f8648e320f8167f9314 100644 (file)
@@ -6467,55 +6467,6 @@ func (s *State) DebugFriendlySetPosFrom(v *ssa.Value) {
        }
 }
 
-// byXoffset implements sort.Interface for []*ir.Name using Xoffset as the ordering.
-type byXoffset []*ir.Name
-
-func (s byXoffset) Len() int           { return len(s) }
-func (s byXoffset) Less(i, j int) bool { return s[i].FrameOffset() < s[j].FrameOffset() }
-func (s byXoffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-func emitStackObjects(e *ssafn, pp *objw.Progs) {
-       var vars []*ir.Name
-       for _, n := range e.curfn.Dcl {
-               if liveness.ShouldTrack(n) && n.Addrtaken() && n.Esc() != ir.EscHeap {
-                       vars = append(vars, n)
-               }
-       }
-       if len(vars) == 0 {
-               return
-       }
-
-       // Sort variables from lowest to highest address.
-       sort.Sort(byXoffset(vars))
-
-       // Populate the stack object data.
-       // Format must match runtime/stack.go:stackObjectRecord.
-       x := base.Ctxt.Lookup(e.curfn.LSym.Name + ".stkobj")
-       e.curfn.LSym.Func().StackObjects = x
-       off := 0
-       off = objw.Uintptr(x, off, uint64(len(vars)))
-       for _, v := range vars {
-               // Note: arguments and return values have non-negative Xoffset,
-               // in which case the offset is relative to argp.
-               // Locals have a negative Xoffset, in which case the offset is relative to varp.
-               off = objw.Uintptr(x, off, uint64(v.FrameOffset()))
-               off = objw.SymPtr(x, off, reflectdata.TypeLinksym(v.Type()), 0)
-       }
-
-       // Emit a funcdata pointing at the stack object data.
-       p := pp.Prog(obj.AFUNCDATA)
-       p.From.SetConst(objabi.FUNCDATA_StackObjects)
-       p.To.Type = obj.TYPE_MEM
-       p.To.Name = obj.NAME_EXTERN
-       p.To.Sym = x
-
-       if base.Flag.Live != 0 {
-               for _, v := range vars {
-                       base.WarnfAt(v.Pos(), "stack object %v %s", v, v.Type().String())
-               }
-       }
-}
-
 // genssa appends entries to pp for each instruction in f.
 func genssa(f *ssa.Func, pp *objw.Progs) {
        var s State
@@ -6523,7 +6474,6 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
        e := f.Frontend().(*ssafn)
 
        s.livenessMap = liveness.Compute(e.curfn, f, e.stkptrsize, pp)
-       emitStackObjects(e, pp)
 
        openDeferInfo := e.curfn.LSym.Func().OpenCodedDeferInfo
        if openDeferInfo != nil {