]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: issue VarDef only for pointer-ful types
authorKeith Randall <khr@golang.org>
Sun, 24 Jul 2022 20:24:21 +0000 (13:24 -0700)
committerKeith Randall <khr@golang.org>
Mon, 22 Aug 2022 18:57:00 +0000 (18:57 +0000)
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>

src/cmd/compile/internal/ssa/check.go
src/cmd/compile/internal/ssa/cse_test.go
src/cmd/compile/internal/ssa/export_test.go
src/cmd/compile/internal/ssagen/ssa.go

index df677e674a04b3c1f1f73d64665d624ebcab11bd..f34b9074197bfcd6e1e5db35e83b760592c50f31 100644 (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())
+                               }
 
                        }
 
index 8052016f3af6928fde492839c8b521b1d814aa63..813ebe43a1d93f66c5cb5163532417e5982fced9 100644 (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",
index 87d1b41419cf3e835ae942b2ee8caa1b54694c09..f98437b62979010f055fd12f3384721558841b5a 100644 (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
 }
index c72cfa5144088351cb4e39fb2ff84348210c6c9a..1fa905bcc9e401634ba6962192c935ce8703587e 100644 (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
 }