cmd/compile: pass types on SSA Store/Move/Zero ops

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>
This commit is contained in:
Cherry Zhang 2017-02-09 09:46:44 -05:00
parent 77b09b8b8d
commit 211c8c9f1a
14 changed files with 217 additions and 97 deletions

View 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()

View 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))
}

View File

@ -19,10 +19,10 @@
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)
@ -31,10 +31,10 @@
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
@ -47,10 +47,10 @@
(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
@ -67,13 +67,13 @@
(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))

View File

@ -31,16 +31,16 @@
(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

View File

@ -795,35 +795,35 @@
(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))))
@ -833,9 +833,9 @@
// 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
@ -847,7 +847,7 @@
(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)

View 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

View 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)
}

View 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",

View 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)

View 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)

View 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)

View 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

View 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)

View 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