mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
04e1176fd2
commit
abbb82957d
1 changed files with 7 additions and 1 deletions
|
|
@ -1941,16 +1941,22 @@ func (s *state) exit() *ssa.Block {
|
||||||
// Store SSAable and heap-escaped PPARAMOUT variables back to stack locations.
|
// Store SSAable and heap-escaped PPARAMOUT variables back to stack locations.
|
||||||
for i, f := range resultFields {
|
for i, f := range resultFields {
|
||||||
n := f.Nname.(*ir.Name)
|
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 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())
|
results[i] = s.variable(n, n.Type())
|
||||||
} else if !n.OnStack() { // result is actually heap allocated
|
} 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)
|
ha := s.expr(n.Heapaddr)
|
||||||
s.instrumentFields(n.Type(), ha, instrumentRead)
|
s.instrumentFields(n.Type(), ha, instrumentRead)
|
||||||
results[i] = s.newValue2(ssa.OpDereference, n.Type(), ha, s.mem())
|
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.
|
} 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,
|
// 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)
|
// 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())
|
results[i] = s.newValue2(ssa.OpDereference, n.Type(), s.addr(n), s.mem())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue