diff options
author | Matthew Dempsky <mdempsky@google.com> | 2021-01-17 22:05:50 -0800 |
---|---|---|
committer | Matthew Dempsky <mdempsky@google.com> | 2021-01-18 06:33:56 +0000 |
commit | 422f38fb6c8d673eaa13669a22768f4fdd91642b (patch) | |
tree | c49ed7010f473eac7c61286e0d53d1c6c969ee49 /src/cmd/compile/internal/liveness | |
parent | 6113db0bb47706b8b5f65b67b87f8277432ca4d2 (diff) | |
download | go-422f38fb6c8d673eaa13669a22768f4fdd91642b.tar.gz go-422f38fb6c8d673eaa13669a22768f4fdd91642b.zip |
[dev.regabi] cmd/compile: move stack objects to liveness
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>
Diffstat (limited to 'src/cmd/compile/internal/liveness')
-rw-r--r-- | src/cmd/compile/internal/liveness/plive.go | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go index c70db6ed18..53ae797fce 100644 --- a/src/cmd/compile/internal/liveness/plive.go +++ b/src/cmd/compile/internal/liveness/plive.go @@ -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: // |