aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/liveness
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-02-19 18:00:48 -0500
committerDavid Chase <drchase@google.com>2021-03-04 16:21:10 +0000
commit3778f8e07d06cabfccd1508295ad67270af078cd (patch)
tree81b1273462ea0c5751571072c47fb3303985b4fc /src/cmd/compile/internal/liveness
parenta2d92b5143ad6ed1b55b71032c5c1f468ba76fd4 (diff)
downloadgo-3778f8e07d06cabfccd1508295ad67270af078cd.tar.gz
go-3778f8e07d06cabfccd1508295ad67270af078cd.zip
cmd/compile: fix pointer maps for morestack
Verified with test and with single step watching changes to register values across morestack calls, after reload. Also added stack-growth test with pointer parameters of varying lifetime. For #40724. Change-Id: Idb5fe27786ac5c6665a734d41e68d3d39de2f4da Reviewed-on: https://go-review.googlesource.com/c/go/+/294429 Trust: David Chase <drchase@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Jeremy Faller <jeremy@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/liveness')
-rw-r--r--src/cmd/compile/internal/liveness/plive.go16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go
index 53ae797fce..48a26cf66a 100644
--- a/src/cmd/compile/internal/liveness/plive.go
+++ b/src/cmd/compile/internal/liveness/plive.go
@@ -297,6 +297,22 @@ func affectedVar(v *ssa.Value) (*ir.Name, ssa.SymEffect) {
n, _ := ssa.AutoVar(v)
return n, ssa.SymWrite
+ case ssa.OpArgIntReg:
+ // This forces the spill slot for the register to be live at function entry.
+ // one of the following holds for a function F with pointer-valued register arg X:
+ // 0. No GC (so an uninitialized spill slot is okay)
+ // 1. GC at entry of F. GC is precise, but the spills around morestack initialize X's spill slot
+ // 2. Stack growth at entry of F. Same as GC.
+ // 3. GC occurs within F itself. This has to be from preemption, and thus GC is conservative.
+ // a. X is in a register -- then X is seen, and the spill slot is also scanned conservatively.
+ // b. X is spilled -- the spill slot is initialized, and scanned conservatively
+ // c. X is not live -- the spill slot is scanned conservatively, and it may contain X from an earlier spill.
+ // 4. GC within G, transitively called from F
+ // a. X is live at call site, therefore is spilled, to its spill slot (which is live because of subsequent LoadReg).
+ // b. X is not live at call site -- but neither is its spill slot.
+ n, _ := ssa.AutoVar(v)
+ return n, ssa.SymRead
+
case ssa.OpVarLive:
return v.Aux.(*ir.Name), ssa.SymRead
case ssa.OpVarDef, ssa.OpVarKill: