aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssagen
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2021-04-15 15:43:22 -0400
committerCherry Zhang <cherryyz@google.com>2021-04-16 16:36:45 +0000
commitabbb82957d823f249dd39e38d448691e86c978bc (patch)
tree5b38f1e4c931f78e4a925419f94c9e678deeec0c /src/cmd/compile/internal/ssagen
parent04e1176fd288f1ceba987d8d2fd9040e45157b38 (diff)
downloadgo-abbb82957d823f249dd39e38d448691e86c978bc.tar.gz
go-abbb82957d823f249dd39e38d448691e86c978bc.zip
cmd/compile: don't insert VarDef for already-initialized results
Currently, when we about to emit code that sets the function results and returns, it emits a VarDef. But in some cases, the result node is actually live and holding useful data. VarDef means that we are about to (re)initialize it so all previous data are dead, but that is not true. Don't insert that. Also don't add VarDef for register results. We are not going to store anything (currently it doesn't cause problem, just unnecessary). Change-Id: I9dd3b70b4a3f5035af028b143fde8fafa2f11fa0 Reviewed-on: https://go-review.googlesource.com/c/go/+/310589 Trust: Cherry Zhang <cherryyz@google.com> Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssagen')
-rw-r--r--src/cmd/compile/internal/ssagen/ssa.go8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
index 8f27777cfc..61f23a9c40 100644
--- a/src/cmd/compile/internal/ssagen/ssa.go
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -1941,16 +1941,22 @@ func (s *state) exit() *ssa.Block {
// Store SSAable and heap-escaped PPARAMOUT variables back to stack locations.
for i, f := range resultFields {
n := f.Nname.(*ir.Name)
- s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
if s.canSSA(n) { // result is in some SSA variable
+ if !n.IsOutputParamInRegisters() {
+ // We are about to store to the result slot.
+ s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
+ }
results[i] = s.variable(n, n.Type())
} else if !n.OnStack() { // result is actually heap allocated
+ // We are about to copy the in-heap result to the result slot.
+ s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
ha := s.expr(n.Heapaddr)
s.instrumentFields(n.Type(), ha, instrumentRead)
results[i] = s.newValue2(ssa.OpDereference, n.Type(), ha, s.mem())
} else { // result is not SSA-able; not escaped, so not on heap, but too large for SSA.
// Before register ABI this ought to be a self-move, home=dest,
// With register ABI, it's still a self-move if parameter is on stack (i.e., too big or overflowed)
+ // No VarDef, as the result slot is already holding live value.
results[i] = s.newValue2(ssa.OpDereference, n.Type(), s.addr(n), s.mem())
}
}