]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: pass types on SSA Store/Move/Zero ops
authorCherry Zhang <cherryyz@google.com>
Thu, 9 Feb 2017 14:46:44 +0000 (09:46 -0500)
committerCherry Zhang <cherryyz@google.com>
Thu, 16 Mar 2017 14:22:53 +0000 (14:22 +0000)
For SSA Store/Move/Zero ops, attach the type of the value being
stored to the op as the Aux field. This type will be used for
write barrier insertion (in a followup CL). Since SSA passes
do not accurately propagate types of values (because of type
casting), we can't simply use type of the store's arguments
for write barrier insertion.

Passes "toolstash -cmp" on std.

Updates #17583.

Change-Id: I051d5e5c482931640d1d7d879b2a6bb91f2e0056
Reviewed-on: https://go-review.googlesource.com/36838
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
14 files changed:
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/type.go
src/cmd/compile/internal/ssa/gen/dec.rules
src/cmd/compile/internal/ssa/gen/dec64.rules
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/gen/rulegen.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewritedec.go
src/cmd/compile/internal/ssa/rewritedec64.go
src/cmd/compile/internal/ssa/rewritegeneric.go
src/cmd/compile/internal/ssa/type.go
src/cmd/compile/internal/ssa/type_test.go
src/cmd/compile/internal/ssa/writebarrier.go

index afa600f5265aa225a0bd07d1620bb91c54ee0d2f..e776d3f9f49a24072fcdf43f4ae85a0571d10552 100644 (file)
@@ -896,7 +896,9 @@ func (s *state) exit() *ssa.Block {
                addr := s.decladdrs[n]
                val := s.variable(n, n.Type)
                s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, n, s.mem())
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, n.Type.Size(), addr, val, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, n.Type.Size(), addr, val, s.mem())
+               store.Aux = n.Type
+               s.vars[&memVar] = store
                // TODO: if val is ever spilled, we'd like to use the
                // PPARAMOUT slot for spilling it. That won't happen
                // currently.
@@ -2129,9 +2131,13 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
                        s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, sn, s.mem())
                }
                capaddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), int64(array_cap), addr)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capaddr, r[2], s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capaddr, r[2], s.mem())
+               store.Aux = Types[TINT]
+               s.vars[&memVar] = store
                if ssa.IsStackAddr(addr) {
-                       s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, pt.Size(), addr, r[0], s.mem())
+                       store := s.newValue3I(ssa.OpStore, ssa.TypeMem, pt.Size(), addr, r[0], s.mem())
+                       store.Aux = pt
+                       s.vars[&memVar] = store
                } else {
                        s.insertWBstore(pt, addr, r[0], 0)
                }
@@ -2154,7 +2160,9 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
                l = s.variable(&lenVar, Types[TINT]) // generates phi for len
                nl = s.newValue2(s.ssaOp(OADD, Types[TINT]), Types[TINT], l, s.constInt(Types[TINT], nargs))
                lenaddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), int64(array_nel), addr)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenaddr, nl, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenaddr, nl, s.mem())
+               store.Aux = Types[TINT]
+               s.vars[&memVar] = store
        }
 
        // Evaluate args
@@ -2188,13 +2196,17 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
                        if haspointers(et) {
                                s.insertWBstore(et, addr, arg.v, 0)
                        } else {
-                               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, et.Size(), addr, arg.v, s.mem())
+                               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, et.Size(), addr, arg.v, s.mem())
+                               store.Aux = et
+                               s.vars[&memVar] = store
                        }
                } else {
                        if haspointers(et) {
                                s.insertWBmove(et, addr, arg.v)
                        } else {
-                               s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(et), addr, arg.v, s.mem())
+                               store := s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(et), addr, arg.v, s.mem())
+                               store.Aux = et
+                               s.vars[&memVar] = store
                        }
                }
        }
@@ -2354,10 +2366,14 @@ func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, skip skipMa
                        return
                }
                if right == nil {
-                       s.vars[&memVar] = s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(t), addr, s.mem())
+                       store := s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(t), addr, s.mem())
+                       store.Aux = t
+                       s.vars[&memVar] = store
                        return
                }
-               s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(t), addr, right, s.mem())
+               store := s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(t), addr, right, s.mem())
+               store.Aux = t
+               s.vars[&memVar] = store
                return
        }
        // Treat as a store.
@@ -2378,7 +2394,9 @@ func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, skip skipMa
                s.storeTypeScalars(t, addr, right, skip)
                return
        }
-       s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), addr, right, s.mem())
+       store := s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), addr, right, s.mem())
+       store.Aux = t
+       s.vars[&memVar] = store
 }
 
 // zeroVal returns the zero value for type t.
@@ -2954,7 +2972,9 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
                        argStart += int64(2 * Widthptr)
                }
                addr := s.constOffPtrSP(ptrto(Types[TUINTPTR]), argStart)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
+               store.Aux = Types[TUINTPTR]
+               s.vars[&memVar] = store
        }
 
        // Defer/go args
@@ -2963,9 +2983,13 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
                argStart := Ctxt.FixedFrameSize()
                argsize := s.constInt32(Types[TUINT32], int32(stksize))
                addr := s.constOffPtrSP(ptrto(Types[TUINT32]), argStart)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, addr, argsize, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, addr, argsize, s.mem())
+               store.Aux = Types[TUINT32]
+               s.vars[&memVar] = store
                addr = s.constOffPtrSP(ptrto(Types[TUINTPTR]), argStart+int64(Widthptr))
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
+               store = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
+               store.Aux = Types[TUINTPTR]
+               s.vars[&memVar] = store
                stksize += 2 * int64(Widthptr)
        }
 
@@ -3328,7 +3352,9 @@ func (s *state) rtcall(fn *obj.LSym, returns bool, results []*Type, args ...*ssa
                off = Rnd(off, t.Alignment())
                ptr := s.constOffPtrSP(t.PtrTo(), off)
                size := t.Size()
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, size, ptr, arg, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, size, ptr, arg, s.mem())
+               store.Aux = t
+               s.vars[&memVar] = store
                off += size
        }
        off = Rnd(off, int64(Widthptr))
@@ -3400,7 +3426,8 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value) {
        } else {
                val = s.newValue3I(ssa.OpMoveWB, ssa.TypeMem, sizeAlignAuxInt(t), left, right, s.mem())
        }
-       val.Aux = &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: Linksym(typenamesym(t))}
+       //val.Aux = &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: Linksym(typenamesym(t))}
+       val.Aux = t
        s.vars[&memVar] = val
 }
 
@@ -3433,7 +3460,9 @@ func (s *state) insertWBstore(t *Type, left, right *ssa.Value, skip skipMask) {
 func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask) {
        switch {
        case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex():
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), left, right, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), left, right, s.mem())
+               store.Aux = t
+               s.vars[&memVar] = store
        case t.IsPtrShaped():
                // no scalar fields.
        case t.IsString():
@@ -3442,22 +3471,30 @@ func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask)
                }
                len := s.newValue1(ssa.OpStringLen, Types[TINT], right)
                lenAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), s.config.IntSize, left)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
+               store.Aux = Types[TINT]
+               s.vars[&memVar] = store
        case t.IsSlice():
                if skip&skipLen == 0 {
                        len := s.newValue1(ssa.OpSliceLen, Types[TINT], right)
                        lenAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), s.config.IntSize, left)
-                       s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
+                       store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
+                       store.Aux = Types[TINT]
+                       s.vars[&memVar] = store
                }
                if skip&skipCap == 0 {
                        cap := s.newValue1(ssa.OpSliceCap, Types[TINT], right)
                        capAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), 2*s.config.IntSize, left)
-                       s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capAddr, cap, s.mem())
+                       store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capAddr, cap, s.mem())
+                       store.Aux = Types[TINT]
+                       s.vars[&memVar] = store
                }
        case t.IsInterface():
                // itab field doesn't need a write barrier (even though it is a pointer).
                itab := s.newValue1(ssa.OpITab, ptrto(Types[TUINT8]), right)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, left, itab, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, left, itab, s.mem())
+               store.Aux = Types[TUINTPTR]
+               s.vars[&memVar] = store
        case t.IsStruct():
                n := t.NumFields()
                for i := 0; i < n; i++ {
@@ -3479,18 +3516,26 @@ func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask)
 func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) {
        switch {
        case t.IsPtrShaped():
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
+               store.Aux = t
+               s.vars[&memVar] = store
        case t.IsString():
                ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), right)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store.Aux = ptrto(Types[TUINT8])
+               s.vars[&memVar] = store
        case t.IsSlice():
                ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), right)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store.Aux = ptrto(Types[TUINT8])
+               s.vars[&memVar] = store
        case t.IsInterface():
                // itab field is treated as a scalar.
                idata := s.newValue1(ssa.OpIData, ptrto(Types[TUINT8]), right)
                idataAddr := s.newValue1I(ssa.OpOffPtr, ptrto(ptrto(Types[TUINT8])), s.config.PtrSize, left)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
+               store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
+               store.Aux = ptrto(Types[TUINT8])
+               s.vars[&memVar] = store
        case t.IsStruct():
                n := t.NumFields()
                for i := 0; i < n; i++ {
@@ -3515,18 +3560,26 @@ func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) {
 func (s *state) storeTypePtrsWB(t *Type, left, right *ssa.Value) {
        switch {
        case t.IsPtrShaped():
-               s.vars[&memVar] = s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
+               store := s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
+               store.Aux = t
+               s.vars[&memVar] = store
        case t.IsString():
                ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), right)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store := s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store.Aux = ptrto(Types[TUINT8])
+               s.vars[&memVar] = store
        case t.IsSlice():
                ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), right)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store := s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
+               store.Aux = ptrto(Types[TUINT8])
+               s.vars[&memVar] = store
        case t.IsInterface():
                // itab field is treated as a scalar.
                idata := s.newValue1(ssa.OpIData, ptrto(Types[TUINT8]), right)
                idataAddr := s.newValue1I(ssa.OpOffPtr, ptrto(ptrto(Types[TUINT8])), s.config.PtrSize, left)
-               s.vars[&memVar] = s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
+               store := s.newValue3I(ssa.OpStoreWB, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
+               store.Aux = ptrto(Types[TUINT8])
+               s.vars[&memVar] = store
        case t.IsStruct():
                n := t.NumFields()
                for i := 0; i < n; i++ {
@@ -4127,7 +4180,9 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
                }
        } else {
                p := s.newValue1(ssa.OpIData, ptrto(n.Type), iface)
-               s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(n.Type), addr, p, s.mem())
+               store := s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(n.Type), addr, p, s.mem())
+               store.Aux = n.Type
+               s.vars[&memVar] = store
        }
        s.vars[&okVar] = s.constBool(true)
        s.endBlock()
@@ -4138,7 +4193,9 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
        if tmp == nil {
                s.vars[valVar] = s.zeroVal(n.Type)
        } else {
-               s.vars[&memVar] = s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(n.Type), addr, s.mem())
+               store := s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(n.Type), addr, s.mem())
+               store.Aux = n.Type
+               s.vars[&memVar] = store
        }
        s.vars[&okVar] = s.constBool(false)
        s.endBlock()
index 3ebe622b6174604c57d1ce4198cad10b39ad4b00..cde9980d5951aa77fd50b01d2c0c9a1377e7689d 100644 (file)
@@ -11,6 +11,7 @@ package gc
 
 import (
        "cmd/compile/internal/ssa"
+       "cmd/internal/obj"
        "cmd/internal/src"
        "fmt"
 )
@@ -1279,3 +1280,17 @@ func (t *Type) IsUntyped() bool {
        }
        return false
 }
+
+// HasPointer returns whether t contains heap pointer.
+// This is used for write barrier insertion, so we ignore
+// pointers to go:notinheap types.
+func (t *Type) HasPointer() bool {
+       if t.IsPtr() && t.Elem().NotInHeap() {
+               return false
+       }
+       return haspointers(t)
+}
+
+func (t *Type) Symbol() *obj.LSym {
+       return Linksym(typenamesym(t))
+}
index 401fba809e058cb8f5b390ee302b1eb52df970f2..97f6a11c74e5c858397f31cf13e28e98d752231d 100644 (file)
       mem)
     )
 (Store [8] dst (ComplexMake real imag) mem) ->
-  (Store [4]
+  (Store [4] {config.fe.TypeFloat32()}
     (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst)
     imag
-    (Store [4] dst real mem))
+    (Store [4] {config.fe.TypeFloat32()} dst real mem))
 (Load <t> ptr mem) && t.IsComplex() && t.Size() == 16 ->
   (ComplexMake
     (Load <config.fe.TypeFloat64()> ptr mem)
       mem)
     )
 (Store [16] dst (ComplexMake real imag) mem) ->
-  (Store [8]
+  (Store [8] {config.fe.TypeFloat64()}
     (OffPtr <config.fe.TypeFloat64().PtrTo()> [8] dst)
     imag
-    (Store [8] dst real mem))
+    (Store [8] {config.fe.TypeFloat64()} dst real mem))
 
 // string ops
 (StringPtr (StringMake ptr _)) -> ptr
       (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] ptr)
       mem))
 (Store [2*config.PtrSize] dst (StringMake ptr len) mem) ->
-  (Store [config.PtrSize]
+  (Store [config.PtrSize] {config.fe.TypeInt()}
     (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] dst)
     len
-    (Store [config.PtrSize] dst ptr mem))
+    (Store [config.PtrSize] {config.fe.TypeBytePtr()} dst ptr mem))
 
 // slice ops
 (SlicePtr (SliceMake ptr _ _ )) -> ptr
       (OffPtr <config.fe.TypeInt().PtrTo()> [2*config.PtrSize] ptr)
       mem))
 (Store [3*config.PtrSize] dst (SliceMake ptr len cap) mem) ->
-  (Store [config.PtrSize]
+  (Store [config.PtrSize] {config.fe.TypeInt()}
     (OffPtr <config.fe.TypeInt().PtrTo()> [2*config.PtrSize] dst)
     cap
-    (Store [config.PtrSize]
+    (Store [config.PtrSize] {config.fe.TypeInt()}
       (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] dst)
       len
-      (Store [config.PtrSize] dst ptr mem)))
+      (Store [config.PtrSize] {config.fe.TypeBytePtr()} dst ptr mem)))
 
 // interface ops
 (ITab (IMake itab _)) -> itab
@@ -86,7 +86,7 @@
       (OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] ptr)
       mem))
 (Store [2*config.PtrSize] dst (IMake itab data) mem) ->
-  (Store [config.PtrSize]
+  (Store [config.PtrSize] {config.fe.TypeBytePtr()}
     (OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] dst)
     data
-    (Store [config.PtrSize] dst itab mem))
+    (Store [config.PtrSize] {config.fe.TypeUintptr()} dst itab mem))
index bfa0beeeb2d665d1d85f4c76e2f2fb6ad142d070..47399e35e2f47d23ae873b15088164c3af12bbb8 100644 (file)
                (Load <config.fe.TypeUInt32()> (OffPtr <config.fe.TypeUInt32().PtrTo()> [4] ptr) mem))
 
 (Store [8] dst (Int64Make hi lo) mem) && !config.BigEndian ->
-       (Store [4]
+       (Store [4] {hi.Type}
                (OffPtr <hi.Type.PtrTo()> [4] dst)
                hi
-               (Store [4] dst lo mem))
+               (Store [4] {lo.Type} dst lo mem))
 
 (Store [8] dst (Int64Make hi lo) mem) && config.BigEndian ->
-       (Store [4]
+       (Store [4] {lo.Type}
                (OffPtr <lo.Type.PtrTo()> [4] dst)
                lo
-               (Store [4] dst hi mem))
+               (Store [4] {hi.Type} dst hi mem))
 
 (Arg {n} [off]) && is64BitInt(v.Type) && !config.BigEndian && v.Type.IsSigned() ->
   (Int64Make
index 73341a52d7e1a5ee94bf66ee8b9db4b1a56e8ccc..29ff6c1c1983d6a6bbb39937b8d08e4ef6a7a1dd 100644 (file)
 
 (Store _ (StructMake0) mem) -> mem
 (Store dst (StructMake1 <t> f0) mem) ->
-  (Store [t.FieldType(0).Size()] (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
+  (Store [t.FieldType(0).Size()] {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
 (Store dst (StructMake2 <t> f0 f1) mem) ->
-  (Store [t.FieldType(1).Size()]
+  (Store [t.FieldType(1).Size()] {t.FieldType(1)}
     (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
     f1
-    (Store [t.FieldType(0).Size()]
+    (Store [t.FieldType(0).Size()] {t.FieldType(0)}
       (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
         f0 mem))
 (Store dst (StructMake3 <t> f0 f1 f2) mem) ->
-  (Store [t.FieldType(2).Size()]
+  (Store [t.FieldType(2).Size()] {t.FieldType(2)}
     (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
     f2
-    (Store [t.FieldType(1).Size()]
+    (Store [t.FieldType(1).Size()] {t.FieldType(1)}
       (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
       f1
-      (Store [t.FieldType(0).Size()]
+      (Store [t.FieldType(0).Size()] {t.FieldType(0)}
         (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
           f0 mem)))
 (Store dst (StructMake4 <t> f0 f1 f2 f3) mem) ->
-  (Store [t.FieldType(3).Size()]
+  (Store [t.FieldType(3).Size()] {t.FieldType(3)}
     (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
     f3
-    (Store [t.FieldType(2).Size()]
+    (Store [t.FieldType(2).Size()] {t.FieldType(2)}
       (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
       f2
-      (Store [t.FieldType(1).Size()]
+      (Store [t.FieldType(1).Size()] {t.FieldType(1)}
         (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
         f1
-        (Store [t.FieldType(0).Size()]
+        (Store [t.FieldType(0).Size()] {t.FieldType(0)}
           (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
             f0 mem))))
 
 
 // un-SSAable values use mem->mem copies
 (Store [size] dst (Load <t> src mem) mem) && !config.fe.CanSSA(t) ->
-       (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] dst src mem)
+       (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] {t} dst src mem)
 (Store [size] dst (Load <t> src mem) (VarDef {x} mem)) && !config.fe.CanSSA(t) ->
-       (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] dst src (VarDef {x} mem))
+       (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] {t} dst src (VarDef {x} mem))
 
 // array ops
 (ArraySelect (ArrayMake1 x)) -> x
   (ArrayMake1 (Load <t.ElemType()> ptr mem))
 
 (Store _ (ArrayMake0) mem) -> mem
-(Store [size] dst (ArrayMake1 e) mem) -> (Store [size] dst e mem)
+(Store [size] dst (ArrayMake1 e) mem) -> (Store [size] {e.Type} dst e mem)
 
 (ArraySelect [0] (Load ptr mem)) -> (Load ptr mem)
 
index 400bdce395ae87104c54cb6a75d94c1771131333..892641d9cd33295294fe632a3ab694da9310eb45 100644 (file)
@@ -286,16 +286,16 @@ var genericOps = []opData{
        {name: "Invalid"},            // unused value
 
        // Memory operations
-       {name: "Load", argLength: 2},                                  // Load from arg0.  arg1=memory
-       {name: "Store", argLength: 3, typ: "Mem", aux: "Int64"},       // Store arg1 to arg0.  arg2=memory, auxint=size.  Returns memory.
-       {name: "Move", argLength: 3, typ: "Mem", aux: "SizeAndAlign"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment.  Returns memory.
-       {name: "Zero", argLength: 2, typ: "Mem", aux: "SizeAndAlign"}, // arg0=destptr, arg1=mem, auxint=size+alignment. Returns memory.
+       {name: "Load", argLength: 2},                                                        // Load from arg0.  arg1=memory
+       {name: "Store", argLength: 3, typ: "Mem", aux: "SymOff", symEffect: "None"},         // Store arg1 to arg0.  arg2=memory, auxint=size, aux=type.  Returns memory.
+       {name: "Move", argLength: 3, typ: "Mem", aux: "SymSizeAndAlign", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment, aux=type.  Returns memory.
+       {name: "Zero", argLength: 2, typ: "Mem", aux: "SymSizeAndAlign", symEffect: "None"}, // arg0=destptr, arg1=mem, auxint=size+alignment, aux=type. Returns memory.
 
        // Memory operations with write barriers.
        // Expand to runtime calls. Write barrier will be removed if write on stack.
-       {name: "StoreWB", argLength: 3, typ: "Mem", aux: "Int64"},                             // Store arg1 to arg0. arg2=memory, auxint=size.  Returns memory.
-       {name: "MoveWB", argLength: 3, typ: "Mem", aux: "SymSizeAndAlign", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment, aux=symbol-of-type (for typedmemmove).  Returns memory.
-       {name: "ZeroWB", argLength: 2, typ: "Mem", aux: "SymSizeAndAlign", symEffect: "None"}, // arg0=destptr, arg1=mem, auxint=size+alignment, aux=symbol-of-type. Returns memory.
+       {name: "StoreWB", argLength: 3, typ: "Mem", aux: "SymOff", symEffect: "None"},         // Store arg1 to arg0. arg2=memory, auxint=size, aux=type.  Returns memory.
+       {name: "MoveWB", argLength: 3, typ: "Mem", aux: "SymSizeAndAlign", symEffect: "None"}, // arg0=destptr, arg1=srcptr, arg2=mem, auxint=size+alignment, aux=type.  Returns memory.
+       {name: "ZeroWB", argLength: 2, typ: "Mem", aux: "SymSizeAndAlign", symEffect: "None"}, // arg0=destptr, arg1=mem, auxint=size+alignment, aux=type. Returns memory.
 
        // Function calls. Arguments to the call have already been written to the stack.
        // Return values appear on the stack. The method receiver, if any, is treated
index c027541ebaf758870e77ec227acd86fe27b5e0d4..fd7b33be120073f72f07c2d82dccf815a9d4280e 100644 (file)
@@ -657,14 +657,14 @@ func parseValue(val string, arch arch, loc string) (op opData, oparch string, ty
        // Sanity check aux, auxint.
        if auxint != "" {
                switch op.aux {
-               case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64", "SymOff", "SymValAndOff", "SymInt32", "SizeAndAlign":
+               case "Bool", "Int8", "Int16", "Int32", "Int64", "Int128", "Float32", "Float64", "SymOff", "SymValAndOff", "SymInt32", "SizeAndAlign", "SymSizeAndAlign":
                default:
                        log.Fatalf("%s: op %s %s can't have auxint", loc, op.name, op.aux)
                }
        }
        if aux != "" {
                switch op.aux {
-               case "String", "Sym", "SymOff", "SymValAndOff", "SymInt32":
+               case "String", "Sym", "SymOff", "SymValAndOff", "SymInt32", "SymSizeAndAlign":
                default:
                        log.Fatalf("%s: op %s %s can't have aux", loc, op.name, op.aux)
                }
index 390455c2bb0feb20d3800c0ceb027cccd2b8bcc9..9abd265f3155f840ef07752b008ba0e512384b00 100644 (file)
@@ -21557,28 +21557,32 @@ var opcodeTable = [...]opInfo{
                generic: true,
        },
        {
-               name:    "Store",
-               auxType: auxInt64,
-               argLen:  3,
-               generic: true,
+               name:      "Store",
+               auxType:   auxSymOff,
+               argLen:    3,
+               symEffect: SymNone,
+               generic:   true,
        },
        {
-               name:    "Move",
-               auxType: auxSizeAndAlign,
-               argLen:  3,
-               generic: true,
+               name:      "Move",
+               auxType:   auxSymSizeAndAlign,
+               argLen:    3,
+               symEffect: SymNone,
+               generic:   true,
        },
        {
-               name:    "Zero",
-               auxType: auxSizeAndAlign,
-               argLen:  2,
-               generic: true,
+               name:      "Zero",
+               auxType:   auxSymSizeAndAlign,
+               argLen:    2,
+               symEffect: SymNone,
+               generic:   true,
        },
        {
-               name:    "StoreWB",
-               auxType: auxInt64,
-               argLen:  3,
-               generic: true,
+               name:      "StoreWB",
+               auxType:   auxSymOff,
+               argLen:    3,
+               symEffect: SymNone,
+               generic:   true,
        },
        {
                name:      "MoveWB",
index 60c18bdd3342ffdfd5f2eb3e3eae62f3425bca45..8a113743a437c3e82fc50d1b852aad54c8e3cc50 100644 (file)
@@ -303,7 +303,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
        _ = b
        // match: (Store [8] dst (ComplexMake real imag) mem)
        // cond:
-       // result: (Store [4]     (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst)     imag     (Store [4] dst real mem))
+       // result: (Store [4] {config.fe.TypeFloat32()}     (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst)     imag     (Store [4] {config.fe.TypeFloat32()} dst real mem))
        for {
                if v.AuxInt != 8 {
                        break
@@ -318,6 +318,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = 4
+               v.Aux = config.fe.TypeFloat32()
                v0 := b.NewValue0(v.Pos, OpOffPtr, config.fe.TypeFloat32().PtrTo())
                v0.AuxInt = 4
                v0.AddArg(dst)
@@ -325,6 +326,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                v.AddArg(imag)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = 4
+               v1.Aux = config.fe.TypeFloat32()
                v1.AddArg(dst)
                v1.AddArg(real)
                v1.AddArg(mem)
@@ -333,7 +335,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [16] dst (ComplexMake real imag) mem)
        // cond:
-       // result: (Store [8]     (OffPtr <config.fe.TypeFloat64().PtrTo()> [8] dst)     imag     (Store [8] dst real mem))
+       // result: (Store [8] {config.fe.TypeFloat64()}     (OffPtr <config.fe.TypeFloat64().PtrTo()> [8] dst)     imag     (Store [8] {config.fe.TypeFloat64()} dst real mem))
        for {
                if v.AuxInt != 16 {
                        break
@@ -348,6 +350,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = 8
+               v.Aux = config.fe.TypeFloat64()
                v0 := b.NewValue0(v.Pos, OpOffPtr, config.fe.TypeFloat64().PtrTo())
                v0.AuxInt = 8
                v0.AddArg(dst)
@@ -355,6 +358,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                v.AddArg(imag)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = 8
+               v1.Aux = config.fe.TypeFloat64()
                v1.AddArg(dst)
                v1.AddArg(real)
                v1.AddArg(mem)
@@ -363,7 +367,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [2*config.PtrSize] dst (StringMake ptr len) mem)
        // cond:
-       // result: (Store [config.PtrSize]     (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] dst)     len     (Store [config.PtrSize] dst ptr mem))
+       // result: (Store [config.PtrSize] {config.fe.TypeInt()}     (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] dst)     len     (Store [config.PtrSize] {config.fe.TypeBytePtr()} dst ptr mem))
        for {
                if v.AuxInt != 2*config.PtrSize {
                        break
@@ -378,6 +382,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = config.PtrSize
+               v.Aux = config.fe.TypeInt()
                v0 := b.NewValue0(v.Pos, OpOffPtr, config.fe.TypeInt().PtrTo())
                v0.AuxInt = config.PtrSize
                v0.AddArg(dst)
@@ -385,6 +390,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                v.AddArg(len)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = config.PtrSize
+               v1.Aux = config.fe.TypeBytePtr()
                v1.AddArg(dst)
                v1.AddArg(ptr)
                v1.AddArg(mem)
@@ -393,7 +399,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [3*config.PtrSize] dst (SliceMake ptr len cap) mem)
        // cond:
-       // result: (Store [config.PtrSize]     (OffPtr <config.fe.TypeInt().PtrTo()> [2*config.PtrSize] dst)     cap     (Store [config.PtrSize]       (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] dst)       len       (Store [config.PtrSize] dst ptr mem)))
+       // result: (Store [config.PtrSize] {config.fe.TypeInt()}     (OffPtr <config.fe.TypeInt().PtrTo()> [2*config.PtrSize] dst)     cap     (Store [config.PtrSize] {config.fe.TypeInt()}       (OffPtr <config.fe.TypeInt().PtrTo()> [config.PtrSize] dst)       len       (Store [config.PtrSize] {config.fe.TypeBytePtr()} dst ptr mem)))
        for {
                if v.AuxInt != 3*config.PtrSize {
                        break
@@ -409,6 +415,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = config.PtrSize
+               v.Aux = config.fe.TypeInt()
                v0 := b.NewValue0(v.Pos, OpOffPtr, config.fe.TypeInt().PtrTo())
                v0.AuxInt = 2 * config.PtrSize
                v0.AddArg(dst)
@@ -416,6 +423,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                v.AddArg(cap)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = config.PtrSize
+               v1.Aux = config.fe.TypeInt()
                v2 := b.NewValue0(v.Pos, OpOffPtr, config.fe.TypeInt().PtrTo())
                v2.AuxInt = config.PtrSize
                v2.AddArg(dst)
@@ -423,6 +431,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                v1.AddArg(len)
                v3 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v3.AuxInt = config.PtrSize
+               v3.Aux = config.fe.TypeBytePtr()
                v3.AddArg(dst)
                v3.AddArg(ptr)
                v3.AddArg(mem)
@@ -432,7 +441,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [2*config.PtrSize] dst (IMake itab data) mem)
        // cond:
-       // result: (Store [config.PtrSize]     (OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] dst)     data     (Store [config.PtrSize] dst itab mem))
+       // result: (Store [config.PtrSize] {config.fe.TypeBytePtr()}     (OffPtr <config.fe.TypeBytePtr().PtrTo()> [config.PtrSize] dst)     data     (Store [config.PtrSize] {config.fe.TypeUintptr()} dst itab mem))
        for {
                if v.AuxInt != 2*config.PtrSize {
                        break
@@ -447,6 +456,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = config.PtrSize
+               v.Aux = config.fe.TypeBytePtr()
                v0 := b.NewValue0(v.Pos, OpOffPtr, config.fe.TypeBytePtr().PtrTo())
                v0.AuxInt = config.PtrSize
                v0.AddArg(dst)
@@ -454,6 +464,7 @@ func rewriteValuedec_OpStore(v *Value, config *Config) bool {
                v.AddArg(data)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = config.PtrSize
+               v1.Aux = config.fe.TypeUintptr()
                v1.AddArg(dst)
                v1.AddArg(itab)
                v1.AddArg(mem)
index d04676fadbe29cf6a14efa6341582b16d8bde160..be1684030dedbd453cc80b1fffa2e5cdb801e7ca 100644 (file)
@@ -2398,7 +2398,7 @@ func rewriteValuedec64_OpStore(v *Value, config *Config) bool {
        _ = b
        // match: (Store [8] dst (Int64Make hi lo) mem)
        // cond: !config.BigEndian
-       // result: (Store [4]           (OffPtr <hi.Type.PtrTo()> [4] dst)              hi              (Store [4] dst lo mem))
+       // result: (Store [4] {hi.Type}                 (OffPtr <hi.Type.PtrTo()> [4] dst)              hi              (Store [4] {lo.Type} dst lo mem))
        for {
                if v.AuxInt != 8 {
                        break
@@ -2416,6 +2416,7 @@ func rewriteValuedec64_OpStore(v *Value, config *Config) bool {
                }
                v.reset(OpStore)
                v.AuxInt = 4
+               v.Aux = hi.Type
                v0 := b.NewValue0(v.Pos, OpOffPtr, hi.Type.PtrTo())
                v0.AuxInt = 4
                v0.AddArg(dst)
@@ -2423,6 +2424,7 @@ func rewriteValuedec64_OpStore(v *Value, config *Config) bool {
                v.AddArg(hi)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = 4
+               v1.Aux = lo.Type
                v1.AddArg(dst)
                v1.AddArg(lo)
                v1.AddArg(mem)
@@ -2431,7 +2433,7 @@ func rewriteValuedec64_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [8] dst (Int64Make hi lo) mem)
        // cond: config.BigEndian
-       // result: (Store [4]           (OffPtr <lo.Type.PtrTo()> [4] dst)              lo              (Store [4] dst hi mem))
+       // result: (Store [4] {lo.Type}                 (OffPtr <lo.Type.PtrTo()> [4] dst)              lo              (Store [4] {hi.Type} dst hi mem))
        for {
                if v.AuxInt != 8 {
                        break
@@ -2449,6 +2451,7 @@ func rewriteValuedec64_OpStore(v *Value, config *Config) bool {
                }
                v.reset(OpStore)
                v.AuxInt = 4
+               v.Aux = lo.Type
                v0 := b.NewValue0(v.Pos, OpOffPtr, lo.Type.PtrTo())
                v0.AuxInt = 4
                v0.AddArg(dst)
@@ -2456,6 +2459,7 @@ func rewriteValuedec64_OpStore(v *Value, config *Config) bool {
                v.AddArg(lo)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = 4
+               v1.Aux = hi.Type
                v1.AddArg(dst)
                v1.AddArg(hi)
                v1.AddArg(mem)
index b998266f2b516e0db5b2359dfc80a4f754a317e4..172e77783d98ed94c3b99f46bc00c699c1adbc83 100644 (file)
@@ -14748,7 +14748,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store dst (StructMake1 <t> f0) mem)
        // cond:
-       // result: (Store [t.FieldType(0).Size()] (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
+       // result: (Store [t.FieldType(0).Size()] {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
        for {
                dst := v.Args[0]
                v_1 := v.Args[1]
@@ -14760,6 +14760,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = t.FieldType(0).Size()
+               v.Aux = t.FieldType(0)
                v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
                v0.AuxInt = 0
                v0.AddArg(dst)
@@ -14770,7 +14771,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store dst (StructMake2 <t> f0 f1) mem)
        // cond:
-       // result: (Store [t.FieldType(1).Size()]     (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)     f1     (Store [t.FieldType(0).Size()]       (OffPtr <t.FieldType(0).PtrTo()> [0] dst)         f0 mem))
+       // result: (Store [t.FieldType(1).Size()] {t.FieldType(1)}     (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)     f1     (Store [t.FieldType(0).Size()] {t.FieldType(0)}       (OffPtr <t.FieldType(0).PtrTo()> [0] dst)         f0 mem))
        for {
                dst := v.Args[0]
                v_1 := v.Args[1]
@@ -14783,6 +14784,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = t.FieldType(1).Size()
+               v.Aux = t.FieldType(1)
                v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
                v0.AuxInt = t.FieldOff(1)
                v0.AddArg(dst)
@@ -14790,6 +14792,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                v.AddArg(f1)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = t.FieldType(0).Size()
+               v1.Aux = t.FieldType(0)
                v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
                v2.AuxInt = 0
                v2.AddArg(dst)
@@ -14801,7 +14804,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store dst (StructMake3 <t> f0 f1 f2) mem)
        // cond:
-       // result: (Store [t.FieldType(2).Size()]     (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)     f2     (Store [t.FieldType(1).Size()]       (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)       f1       (Store [t.FieldType(0).Size()]         (OffPtr <t.FieldType(0).PtrTo()> [0] dst)           f0 mem)))
+       // result: (Store [t.FieldType(2).Size()] {t.FieldType(2)}     (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)     f2     (Store [t.FieldType(1).Size()] {t.FieldType(1)}       (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)       f1       (Store [t.FieldType(0).Size()] {t.FieldType(0)}         (OffPtr <t.FieldType(0).PtrTo()> [0] dst)           f0 mem)))
        for {
                dst := v.Args[0]
                v_1 := v.Args[1]
@@ -14815,6 +14818,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = t.FieldType(2).Size()
+               v.Aux = t.FieldType(2)
                v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
                v0.AuxInt = t.FieldOff(2)
                v0.AddArg(dst)
@@ -14822,6 +14826,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                v.AddArg(f2)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = t.FieldType(1).Size()
+               v1.Aux = t.FieldType(1)
                v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
                v2.AuxInt = t.FieldOff(1)
                v2.AddArg(dst)
@@ -14829,6 +14834,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                v1.AddArg(f1)
                v3 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v3.AuxInt = t.FieldType(0).Size()
+               v3.Aux = t.FieldType(0)
                v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
                v4.AuxInt = 0
                v4.AddArg(dst)
@@ -14841,7 +14847,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store dst (StructMake4 <t> f0 f1 f2 f3) mem)
        // cond:
-       // result: (Store [t.FieldType(3).Size()]     (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)     f3     (Store [t.FieldType(2).Size()]       (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)       f2       (Store [t.FieldType(1).Size()]         (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)         f1         (Store [t.FieldType(0).Size()]           (OffPtr <t.FieldType(0).PtrTo()> [0] dst)             f0 mem))))
+       // result: (Store [t.FieldType(3).Size()] {t.FieldType(3)}     (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)     f3     (Store [t.FieldType(2).Size()] {t.FieldType(2)}       (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)       f2       (Store [t.FieldType(1).Size()] {t.FieldType(1)}         (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)         f1         (Store [t.FieldType(0).Size()] {t.FieldType(0)}           (OffPtr <t.FieldType(0).PtrTo()> [0] dst)             f0 mem))))
        for {
                dst := v.Args[0]
                v_1 := v.Args[1]
@@ -14856,6 +14862,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = t.FieldType(3).Size()
+               v.Aux = t.FieldType(3)
                v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(3).PtrTo())
                v0.AuxInt = t.FieldOff(3)
                v0.AddArg(dst)
@@ -14863,6 +14870,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                v.AddArg(f3)
                v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v1.AuxInt = t.FieldType(2).Size()
+               v1.Aux = t.FieldType(2)
                v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
                v2.AuxInt = t.FieldOff(2)
                v2.AddArg(dst)
@@ -14870,6 +14878,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                v1.AddArg(f2)
                v3 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v3.AuxInt = t.FieldType(1).Size()
+               v3.Aux = t.FieldType(1)
                v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
                v4.AuxInt = t.FieldOff(1)
                v4.AddArg(dst)
@@ -14877,6 +14886,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                v3.AddArg(f1)
                v5 := b.NewValue0(v.Pos, OpStore, TypeMem)
                v5.AuxInt = t.FieldType(0).Size()
+               v5.Aux = t.FieldType(0)
                v6 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
                v6.AuxInt = 0
                v6.AddArg(dst)
@@ -14890,7 +14900,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [size] dst (Load <t> src mem) mem)
        // cond: !config.fe.CanSSA(t)
-       // result: (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] dst src mem)
+       // result: (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] {t} dst src mem)
        for {
                size := v.AuxInt
                dst := v.Args[0]
@@ -14909,6 +14919,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                }
                v.reset(OpMove)
                v.AuxInt = MakeSizeAndAlign(size, t.Alignment()).Int64()
+               v.Aux = t
                v.AddArg(dst)
                v.AddArg(src)
                v.AddArg(mem)
@@ -14916,7 +14927,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [size] dst (Load <t> src mem) (VarDef {x} mem))
        // cond: !config.fe.CanSSA(t)
-       // result: (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] dst src (VarDef {x} mem))
+       // result: (Move [MakeSizeAndAlign(size, t.Alignment()).Int64()] {t} dst src (VarDef {x} mem))
        for {
                size := v.AuxInt
                dst := v.Args[0]
@@ -14940,6 +14951,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                }
                v.reset(OpMove)
                v.AuxInt = MakeSizeAndAlign(size, t.Alignment()).Int64()
+               v.Aux = t
                v.AddArg(dst)
                v.AddArg(src)
                v0 := b.NewValue0(v.Pos, OpVarDef, TypeMem)
@@ -14964,7 +14976,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
        }
        // match: (Store [size] dst (ArrayMake1 e) mem)
        // cond:
-       // result: (Store [size] dst e mem)
+       // result: (Store [size] {e.Type} dst e mem)
        for {
                size := v.AuxInt
                dst := v.Args[0]
@@ -14976,6 +14988,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
                mem := v.Args[2]
                v.reset(OpStore)
                v.AuxInt = size
+               v.Aux = e.Type
                v.AddArg(dst)
                v.AddArg(e)
                v.AddArg(mem)
index 3ebee6a8f1dab1c40d358b738f592f18aa0933b1..0936cc5184639af96f42323bd16c1114402a80ba 100644 (file)
@@ -4,6 +4,8 @@
 
 package ssa
 
+import "cmd/internal/obj"
+
 // TODO: use go/types instead?
 
 // A type interface used to import cmd/internal/gc:Type
@@ -39,9 +41,12 @@ type Type interface {
 
        NumElem() int64 // # of elements of an array
 
+       HasPointer() bool // has heap pointer
+
        String() string
        SimpleString() string // a coarser generic description of T, e.g. T's underlying type
        Compare(Type) Cmp     // compare types, returning one of CMPlt, CMPeq, CMPgt.
+       Symbol() *obj.LSym    // the symbol of the type
 }
 
 // Special compiler-only types.
@@ -80,6 +85,8 @@ func (t *CompilerType) FieldType(i int) Type   { panic("not implemented") }
 func (t *CompilerType) FieldOff(i int) int64   { panic("not implemented") }
 func (t *CompilerType) FieldName(i int) string { panic("not implemented") }
 func (t *CompilerType) NumElem() int64         { panic("not implemented") }
+func (t *CompilerType) HasPointer() bool       { panic("not implemented") }
+func (t *CompilerType) Symbol() *obj.LSym      { panic("not implemented") }
 
 type TupleType struct {
        first  Type
@@ -122,6 +129,8 @@ func (t *TupleType) FieldType(i int) Type {
 func (t *TupleType) FieldOff(i int) int64   { panic("not implemented") }
 func (t *TupleType) FieldName(i int) string { panic("not implemented") }
 func (t *TupleType) NumElem() int64         { panic("not implemented") }
+func (t *TupleType) HasPointer() bool       { panic("not implemented") }
+func (t *TupleType) Symbol() *obj.LSym      { panic("not implemented") }
 
 // Cmp is a comparison between values a and b.
 // -1 if a < b
index 2f917288de9730388859b4785b38dcd442316507..90958995ceddc050103b52efc54f484353581776 100644 (file)
@@ -4,6 +4,8 @@
 
 package ssa
 
+import "cmd/internal/obj"
+
 // Stub implementation used for testing.
 type TypeImpl struct {
        Size_   int64
@@ -50,6 +52,8 @@ func (t *TypeImpl) FieldType(i int) Type   { panic("not implemented") }
 func (t *TypeImpl) FieldOff(i int) int64   { panic("not implemented") }
 func (t *TypeImpl) FieldName(i int) string { panic("not implemented") }
 func (t *TypeImpl) NumElem() int64         { panic("not implemented") }
+func (t *TypeImpl) HasPointer() bool       { return t.Ptr }
+func (t *TypeImpl) Symbol() *obj.LSym      { panic("not implemented") }
 
 func (t *TypeImpl) Equal(u Type) bool {
        x, ok := u.(*TypeImpl)
index 0b82a5ba4cf1fb75d26de05fdfe16a6221feb084..961cf2b2a84e790de2ca139fc76a81330a587b78 100644 (file)
@@ -159,7 +159,10 @@ func writebarrier(f *Func) {
                        var val *Value
                        ptr := w.Args[0]
                        siz := w.AuxInt
-                       typ := w.Aux // only non-nil for MoveWB, ZeroWB
+                       var typ interface{}
+                       if w.Op != OpStoreWB {
+                               typ = &ExternSymbol{Typ: f.Config.fe.TypeUintptr(), Sym: w.Aux.(Type).Symbol()}
+                       }
                        pos = w.Pos
 
                        var op Op