1
0
mirror of https://github.com/golang/go synced 2024-11-17 09:14:46 -07:00

cmd/compile: issue VarDef only for pointer-ful types

Use OpVarDef only when the variable being defined has pointers in it.
VarDef markers are only used for liveness analysis, and that only
runs on pointer-ful variables.

Fixes #53810

Change-Id: I09b0ef7ed31e72528916fe79325f80bbe69ff9b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/419320
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
This commit is contained in:
Keith Randall 2022-07-24 13:24:21 -07:00
parent a726c9f662
commit a74e5f584e
4 changed files with 28 additions and 10 deletions

View File

@ -5,6 +5,7 @@
package ssa
import (
"cmd/compile/internal/ir"
"cmd/internal/obj/s390x"
"math"
"math/bits"
@ -312,6 +313,10 @@ func checkFunc(f *Func) {
if !v.Args[1].Type.IsInteger() {
f.Fatalf("bad arg 1 type to %s: want integer, have %s", v.Op, v.Args[1].LongString())
}
case OpVarDef:
if !v.Aux.(*ir.Name).Type().HasPointers() {
f.Fatalf("vardef must have pointer type %s", v.Aux.(*ir.Name).Type().String())
}
}

View File

@ -22,7 +22,7 @@ func TestCSEAuxPartitionBug(t *testing.T) {
arg1Aux := &tstAux{"arg1-aux"}
arg2Aux := &tstAux{"arg2-aux"}
arg3Aux := &tstAux{"arg3-aux"}
a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8)
a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8.PtrTo())
// construct lots of values with args that have aux values and place
// them in an order that triggers the bug
@ -93,7 +93,7 @@ func TestCSEAuxPartitionBug(t *testing.T) {
// TestZCSE tests the zero arg cse.
func TestZCSE(t *testing.T) {
c := testConfig(t)
a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8)
a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8.PtrTo())
fun := c.Fun("entry",
Bloc("entry",

View File

@ -72,6 +72,7 @@ func (TestFrontend) StringData(s string) *obj.LSym {
}
func (TestFrontend) Auto(pos src.XPos, t *types.Type) *ir.Name {
n := ir.NewNameAt(pos, &types.Sym{Name: "aFakeAuto"})
n.SetType(t)
n.Class = ir.PAUTO
return n
}

View File

@ -630,7 +630,9 @@ func (s *state) zeroResults() {
if typ := n.Type(); TypeOK(typ) {
s.assign(n, s.zeroVal(typ), false, 0)
} else {
s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
if typ.HasPointers() {
s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, n, s.mem())
}
s.zero(n.Type(), s.decladdrs[n])
}
}
@ -1978,14 +1980,16 @@ func (s *state) exit() *ssa.Block {
for i, f := range resultFields {
n := f.Nname.(*ir.Name)
if s.canSSA(n) { // result is in some SSA variable
if !n.IsOutputParamInRegisters() {
if !n.IsOutputParamInRegisters() && n.Type().HasPointers() {
// 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())
if n.Type().HasPointers() {
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())
@ -3607,7 +3611,7 @@ func (s *state) assign(left ir.Node, right *ssa.Value, deref bool, skip skipMask
// If this assignment clobbers an entire local variable, then emit
// OpVarDef so liveness analysis knows the variable is redefined.
if base, ok := clobberBase(left).(*ir.Name); ok && base.OnStack() && skip == 0 {
if base, ok := clobberBase(left).(*ir.Name); ok && base.OnStack() && skip == 0 && t.HasPointers() {
s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !ir.IsAutoTmp(base))
}
@ -4843,14 +4847,18 @@ func (s *state) openDeferSave(t *types.Type, val *ssa.Value) *ssa.Value {
// Force the tmp storing this defer function to be declared in the entry
// block, so that it will be live for the defer exit code (which will
// actually access it only if the associated defer call has been activated).
s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
if t.HasPointers() {
s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarDef, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
}
s.defvars[s.f.Entry.ID][memVar] = s.f.Entry.NewValue1A(src.NoXPos, ssa.OpVarLive, types.TypeMem, temp, s.defvars[s.f.Entry.ID][memVar])
addrTemp = s.f.Entry.NewValue2A(src.NoXPos, ssa.OpLocalAddr, types.NewPtr(temp.Type()), temp, s.sp, s.defvars[s.f.Entry.ID][memVar])
} else {
// Special case if we're still in the entry block. We can't use
// the above code, since s.defvars[s.f.Entry.ID] isn't defined
// until we end the entry block with s.endBlock().
s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, temp, s.mem(), false)
if t.HasPointers() {
s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, temp, s.mem(), false)
}
s.vars[memVar] = s.newValue1Apos(ssa.OpVarLive, types.TypeMem, temp, s.mem(), false)
addrTemp = s.newValue2Apos(ssa.OpLocalAddr, types.NewPtr(temp.Type()), temp, s.sp, s.mem(), false)
}
@ -5032,7 +5040,9 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
t := deferstruct()
d := typecheck.TempAt(n.Pos(), s.curfn, t)
s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem())
if t.HasPointers() {
s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, d, s.mem())
}
addr := s.addr(d)
// Must match deferstruct() below and src/runtime/runtime2.go:_defer.
@ -6428,7 +6438,9 @@ func (s *state) dottype1(pos src.XPos, src, dst *types.Type, iface, source, targ
// temp allocates a temp of type t at position pos
func (s *state) temp(pos src.XPos, t *types.Type) (*ir.Name, *ssa.Value) {
tmp := typecheck.TempAt(pos, s.curfn, t)
s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem())
if t.HasPointers() {
s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, tmp, s.mem())
}
addr := s.addr(tmp)
return tmp, addr
}