aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/liveness
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2021-04-11 12:42:49 -0400
committerCherry Zhang <cherryyz@google.com>2021-04-14 21:00:20 +0000
commit23f8c203f026814ddc4ba4538f900d8151eb6840 (patch)
tree2aa865117c54427b314177f604b6dba44a26c6fc /src/cmd/compile/internal/liveness
parent1a8f0a79619bee4b0040888a5703e38f8117d682 (diff)
downloadgo-23f8c203f026814ddc4ba4538f900d8151eb6840.tar.gz
go-23f8c203f026814ddc4ba4538f900d8151eb6840.zip
cmd/compile: rework/reduce partially lived argument spilling
In CL 307909 we generate code that spills pointer-typed argument registers if it is part of an SSA-able aggregate. The current code spill the register unconditionally. Sometimes it is unnecessary, because it is already spilled, or it is never live. This CL reworks the spill generation. We move it to the end of compilation, after liveness analysis, so we have information about if a spill is necessary, and only generate spills for the necessary ones. Change-Id: I8d60be9b2c47651aeda14f5e2d1bbd207c134b26 Reviewed-on: https://go-review.googlesource.com/c/go/+/309331 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/cmd/compile/internal/liveness')
-rw-r--r--src/cmd/compile/internal/liveness/plive.go20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go
index 4395aaeeb6..53feb6cc32 100644
--- a/src/cmd/compile/internal/liveness/plive.go
+++ b/src/cmd/compile/internal/liveness/plive.go
@@ -141,6 +141,11 @@ type liveness struct {
cache progeffectscache
+ // partLiveArgs includes input arguments (PPARAM) that may
+ // be partially live. That is, it is considered live because
+ // a part of it is used, but we may not initialize all parts.
+ partLiveArgs map[*ir.Name]bool
+
doClobber bool // Whether to clobber dead stack slots in this function.
}
@@ -268,6 +273,12 @@ func (lv *liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
}
}
+ if n.Class == ir.PPARAM && !n.Addrtaken() && n.Type().Width > int64(types.PtrSize) {
+ // Only aggregate-typed arguments that are not address-taken can be
+ // partially live.
+ lv.partLiveArgs[n] = true
+ }
+
var effect liveEffect
// Read is a read, obviously.
//
@@ -394,6 +405,8 @@ func newliveness(fn *ir.Func, f *ssa.Func, vars []*ir.Name, idx map[*ir.Name]int
lv.markUnsafePoints()
+ lv.partLiveArgs = make(map[*ir.Name]bool)
+
lv.enableClobber()
return lv
@@ -1310,8 +1323,9 @@ func (lv *liveness) emit() (argsSym, liveSym *obj.LSym) {
// Entry pointer for Compute analysis. Solves for the Compute of
// pointer variables in the function and emits a runtime data
// structure read by the garbage collector.
-// Returns a map from GC safe points to their corresponding stack map index.
-func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) Map {
+// Returns a map from GC safe points to their corresponding stack map index,
+// and a map that contains all input parameters that may be partially live.
+func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) (Map, map[*ir.Name]bool) {
// Construct the global liveness state.
vars, idx := getvariables(curfn)
lv := newliveness(curfn, f, vars, idx, stkptrsize)
@@ -1373,7 +1387,7 @@ func Compute(curfn *ir.Func, f *ssa.Func, stkptrsize int64, pp *objw.Progs) Map
p.To.Sym = x
}
- return lv.livenessMap
+ return lv.livenessMap, lv.partLiveArgs
}
func (lv *liveness) emitStackObjects() *obj.LSym {