Skip to content

Commit

Permalink
cmd/compile: use type information in Aux for Store size
Browse files Browse the repository at this point in the history
Remove size AuxInt in Store, and alignment in Move/Zero. We still
pass size AuxInt to Move/Zero, as it is used for partial Move/Zero
lowering (e.g. cmd/compile/internal/ssa/gen/386.rules:288).
SizeAndAlign is gone.

Passes "toolstash -cmp" on std.

Change-Id: I1ca34652b65dd30de886940e789fcf41d521475d
Reviewed-on: https://go-review.googlesource.com/38150
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
  • Loading branch information
cherrymui committed Mar 16, 2017
1 parent d75925d commit c8f38b3
Show file tree
Hide file tree
Showing 41 changed files with 2,007 additions and 2,108 deletions.
1 change: 0 additions & 1 deletion src/cmd/compile/fmt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,6 @@ var knownFormats = map[string]string{
"cmd/compile/internal/ssa.Location %v": "",
"cmd/compile/internal/ssa.Op %s": "",
"cmd/compile/internal/ssa.Op %v": "",
"cmd/compile/internal/ssa.SizeAndAlign %s": "",
"cmd/compile/internal/ssa.Type %s": "",
"cmd/compile/internal/ssa.Type %v": "",
"cmd/compile/internal/ssa.ValAndOff %s": "",
Expand Down
88 changes: 27 additions & 61 deletions src/cmd/compile/internal/gc/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,11 @@ func (s *state) newValue3I(op ssa.Op, t ssa.Type, aux int64, arg0, arg1, arg2 *s
return s.curBlock.NewValue3I(s.peekPos(), op, t, aux, arg0, arg1, arg2)
}

// newValue3A adds a new value with three arguments and an aux value to the current block.
func (s *state) newValue3A(op ssa.Op, t ssa.Type, aux interface{}, arg0, arg1, arg2 *ssa.Value) *ssa.Value {
return s.curBlock.NewValue3A(s.peekPos(), op, t, aux, arg0, arg1, arg2)
}

// newValue4 adds a new value with four arguments to the current block.
func (s *state) newValue4(op ssa.Op, t ssa.Type, arg0, arg1, arg2, arg3 *ssa.Value) *ssa.Value {
return s.curBlock.NewValue4(s.peekPos(), op, t, arg0, arg1, arg2, arg3)
Expand Down Expand Up @@ -885,9 +890,7 @@ 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())
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, n.Type.Size(), addr, val, s.mem())
store.Aux = n.Type
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, n.Type, addr, val, s.mem())
// TODO: if val is ever spilled, we'd like to use the
// PPARAMOUT slot for spilling it. That won't happen
// currently.
Expand Down Expand Up @@ -2120,12 +2123,8 @@ 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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capaddr, r[2], s.mem())
store.Aux = Types[TINT]
s.vars[&memVar] = store
store = s.newValue3I(ssa.OpStore, ssa.TypeMem, pt.Size(), addr, r[0], s.mem())
store.Aux = pt
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], capaddr, r[2], s.mem())
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, pt, addr, r[0], s.mem())
// load the value we just stored to avoid having to spill it
s.vars[&ptrVar] = s.newValue2(ssa.OpLoad, pt, addr, s.mem())
s.vars[&lenVar] = r[1] // avoid a spill in the fast path
Expand All @@ -2145,9 +2144,7 @@ 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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenaddr, nl, s.mem())
store.Aux = Types[TINT]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], lenaddr, nl, s.mem())
}

// Evaluate args
Expand Down Expand Up @@ -2178,7 +2175,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
if arg.store {
s.storeType(et, addr, arg.v, 0)
} else {
store := s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(et), addr, arg.v, s.mem())
store := s.newValue3I(ssa.OpMove, ssa.TypeMem, et.Size(), addr, arg.v, s.mem())
store.Aux = et
s.vars[&memVar] = store
}
Expand Down Expand Up @@ -2343,9 +2340,9 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
// Treat as a mem->mem move.
var store *ssa.Value
if right == nil {
store = s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(t), addr, s.mem())
store = s.newValue2I(ssa.OpZero, ssa.TypeMem, t.Size(), addr, s.mem())
} else {
store = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(t), addr, right, s.mem())
store = s.newValue3I(ssa.OpMove, ssa.TypeMem, t.Size(), addr, right, s.mem())
}
store.Aux = t
s.vars[&memVar] = store
Expand Down Expand Up @@ -2928,9 +2925,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
argStart += int64(2 * Widthptr)
}
addr := s.constOffPtrSP(ptrto(Types[TUINTPTR]), argStart)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
store.Aux = Types[TUINTPTR]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINTPTR], addr, rcvr, s.mem())
}

// Defer/go args
Expand All @@ -2939,13 +2934,9 @@ 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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, addr, argsize, s.mem())
store.Aux = Types[TUINT32]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINT32], addr, argsize, s.mem())
addr = s.constOffPtrSP(ptrto(Types[TUINTPTR]), argStart+int64(Widthptr))
store = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
store.Aux = Types[TUINTPTR]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINTPTR], addr, closure, s.mem())
stksize += 2 * int64(Widthptr)
}

Expand Down Expand Up @@ -3308,9 +3299,7 @@ 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()
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, size, ptr, arg, s.mem())
store.Aux = t
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, ptr, arg, s.mem())
off += size
}
off = Rnd(off, int64(Widthptr))
Expand Down Expand Up @@ -3366,9 +3355,7 @@ func (s *state) storeType(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():
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, t.Size(), left, right, s.mem())
store.Aux = t
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, left, right, s.mem())
case t.IsPtrShaped():
// no scalar fields.
case t.IsString():
Expand All @@ -3377,30 +3364,22 @@ 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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
store.Aux = Types[TINT]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], lenAddr, len, s.mem())
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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
store.Aux = Types[TINT]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], lenAddr, len, s.mem())
}
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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capAddr, cap, s.mem())
store.Aux = Types[TINT]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TINT], capAddr, cap, s.mem())
}
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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, left, itab, s.mem())
store.Aux = Types[TUINTPTR]
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, Types[TUINTPTR], left, itab, s.mem())
case t.IsStruct():
n := t.NumFields()
for i := 0; i < n; i++ {
Expand All @@ -3422,26 +3401,18 @@ 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():
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
store.Aux = t
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, t, left, right, s.mem())
case t.IsString():
ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), right)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
store.Aux = ptrto(Types[TUINT8])
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, ptrto(Types[TUINT8]), left, ptr, s.mem())
case t.IsSlice():
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), right)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
store.Aux = ptrto(Types[TUINT8])
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, ptrto(Types[TUINT8]), left, ptr, s.mem())
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)
store := s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
store.Aux = ptrto(Types[TUINT8])
s.vars[&memVar] = store
s.vars[&memVar] = s.newValue3A(ssa.OpStore, ssa.TypeMem, ptrto(Types[TUINT8]), idataAddr, idata, s.mem())
case t.IsStruct():
n := t.NumFields()
for i := 0; i < n; i++ {
Expand Down Expand Up @@ -4042,7 +4013,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
}
} else {
p := s.newValue1(ssa.OpIData, ptrto(n.Type), iface)
store := s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(n.Type), addr, p, s.mem())
store := s.newValue3I(ssa.OpMove, ssa.TypeMem, n.Type.Size(), addr, p, s.mem())
store.Aux = n.Type
s.vars[&memVar] = store
}
Expand All @@ -4055,7 +4026,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
if tmp == nil {
s.vars[valVar] = s.zeroVal(n.Type)
} else {
store := s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(n.Type), addr, s.mem())
store := s.newValue2I(ssa.OpZero, ssa.TypeMem, n.Type.Size(), addr, s.mem())
store.Aux = n.Type
s.vars[&memVar] = store
}
Expand Down Expand Up @@ -4406,11 +4377,6 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
}
}

// sizeAlignAuxInt returns an AuxInt encoding the size and alignment of type t.
func sizeAlignAuxInt(t *Type) int64 {
return ssa.MakeSizeAndAlign(t.Size(), t.Alignment()).Int64()
}

// extendIndex extends v to a full int width.
// panic using the given function if v does not fit in an int (only on 32-bit archs).
func (s *state) extendIndex(v *ssa.Value, panicfn *obj.LSym) *ssa.Value {
Expand Down
6 changes: 2 additions & 4 deletions src/cmd/compile/internal/ssa/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,9 @@ func checkFunc(f *Func) {
if !isExactFloat32(v) {
f.Fatalf("value %v has an AuxInt value that is not an exact float32", v)
}
case auxSizeAndAlign:
canHaveAuxInt = true
case auxString, auxSym:
case auxString, auxSym, auxTyp:
canHaveAux = true
case auxSymOff, auxSymValAndOff, auxSymSizeAndAlign:
case auxSymOff, auxSymValAndOff, auxTypSize:
canHaveAuxInt = true
canHaveAux = true
case auxSymInt32:
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/ssa/cse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestCSEAuxPartitionBug(t *testing.T) {
Valu("r3", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"),
Valu("r5", OpAdd64, TypeInt64, 0, nil, "r2", "r3"),
Valu("r10", OpAdd64, TypeInt64, 0, nil, "r6", "r9"),
Valu("rstore", OpStore, TypeMem, 8, nil, "raddr", "r10", "raddrdef"),
Valu("rstore", OpStore, TypeMem, 0, TypeInt64, "raddr", "r10", "raddrdef"),
Goto("exit")),
Bloc("exit",
Exit("rstore")))
Expand Down Expand Up @@ -104,7 +104,7 @@ func TestZCSE(t *testing.T) {
Valu("r3", OpAdd64, TypeInt64, 0, nil, "r1", "r2"),
Valu("raddr", OpAddr, TypeInt64Ptr, 0, nil, "sp"),
Valu("raddrdef", OpVarDef, TypeMem, 0, nil, "start"),
Valu("rstore", OpStore, TypeMem, 8, nil, "raddr", "r3", "raddrdef"),
Valu("rstore", OpStore, TypeMem, 0, TypeInt64, "raddr", "r3", "raddrdef"),
Goto("exit")),
Bloc("exit",
Exit("rstore")))
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/ssa/deadstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ func dse(f *Func) {
if v.Op == OpStore || v.Op == OpZero {
var sz int64
if v.Op == OpStore {
sz = v.AuxInt
sz = v.Aux.(Type).Size()
} else { // OpZero
sz = SizeAndAlign(v.AuxInt).Size()
sz = v.AuxInt
}
if shadowedSize := int64(shadowed.get(v.Args[0].ID)); shadowedSize != -1 && shadowedSize >= sz {
// Modify store into a copy
Expand Down
20 changes: 10 additions & 10 deletions src/cmd/compile/internal/ssa/deadstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ func TestDeadStore(t *testing.T) {
Valu("addr1", OpAddr, ptrType, 0, nil, "sb"),
Valu("addr2", OpAddr, ptrType, 0, nil, "sb"),
Valu("addr3", OpAddr, ptrType, 0, nil, "sb"),
Valu("zero1", OpZero, TypeMem, 1, nil, "addr3", "start"),
Valu("store1", OpStore, TypeMem, 1, nil, "addr1", "v", "zero1"),
Valu("store2", OpStore, TypeMem, 1, nil, "addr2", "v", "store1"),
Valu("store3", OpStore, TypeMem, 1, nil, "addr1", "v", "store2"),
Valu("store4", OpStore, TypeMem, 1, nil, "addr3", "v", "store3"),
Valu("zero1", OpZero, TypeMem, 1, TypeBool, "addr3", "start"),
Valu("store1", OpStore, TypeMem, 0, TypeBool, "addr1", "v", "zero1"),
Valu("store2", OpStore, TypeMem, 0, TypeBool, "addr2", "v", "store1"),
Valu("store3", OpStore, TypeMem, 0, TypeBool, "addr1", "v", "store2"),
Valu("store4", OpStore, TypeMem, 0, TypeBool, "addr3", "v", "store3"),
Goto("exit")),
Bloc("exit",
Exit("store3")))
Expand Down Expand Up @@ -54,7 +54,7 @@ func TestDeadStorePhi(t *testing.T) {
Goto("loop")),
Bloc("loop",
Valu("phi", OpPhi, TypeMem, 0, nil, "start", "store"),
Valu("store", OpStore, TypeMem, 1, nil, "addr", "v", "phi"),
Valu("store", OpStore, TypeMem, 0, TypeBool, "addr", "v", "phi"),
If("v", "loop", "exit")),
Bloc("exit",
Exit("store")))
Expand All @@ -79,8 +79,8 @@ func TestDeadStoreTypes(t *testing.T) {
Valu("v", OpConstBool, TypeBool, 1, nil),
Valu("addr1", OpAddr, t1, 0, nil, "sb"),
Valu("addr2", OpAddr, t2, 0, nil, "sb"),
Valu("store1", OpStore, TypeMem, 1, nil, "addr1", "v", "start"),
Valu("store2", OpStore, TypeMem, 1, nil, "addr2", "v", "store1"),
Valu("store1", OpStore, TypeMem, 0, TypeBool, "addr1", "v", "start"),
Valu("store2", OpStore, TypeMem, 0, TypeBool, "addr2", "v", "store1"),
Goto("exit")),
Bloc("exit",
Exit("store2")))
Expand Down Expand Up @@ -108,8 +108,8 @@ func TestDeadStoreUnsafe(t *testing.T) {
Valu("sb", OpSB, TypeInvalid, 0, nil),
Valu("v", OpConstBool, TypeBool, 1, nil),
Valu("addr1", OpAddr, ptrType, 0, nil, "sb"),
Valu("store1", OpStore, TypeMem, 8, nil, "addr1", "v", "start"), // store 8 bytes
Valu("store2", OpStore, TypeMem, 1, nil, "addr1", "v", "store1"), // store 1 byte
Valu("store1", OpStore, TypeMem, 0, TypeInt64, "addr1", "v", "start"), // store 8 bytes
Valu("store2", OpStore, TypeMem, 0, TypeBool, "addr1", "v", "store1"), // store 1 byte
Goto("exit")),
Bloc("exit",
Exit("store2")))
Expand Down
15 changes: 15 additions & 0 deletions src/cmd/compile/internal/ssa/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,21 @@ func (b *Block) NewValue3I(pos src.XPos, op Op, t Type, auxint int64, arg0, arg1
return v
}

// NewValue3A returns a new value in the block with three argument and an aux value.
func (b *Block) NewValue3A(pos src.XPos, op Op, t Type, aux interface{}, arg0, arg1, arg2 *Value) *Value {
v := b.Func.newValue(op, t, b, pos)
v.AuxInt = 0
v.Aux = aux
v.Args = v.argstorage[:3]
v.argstorage[0] = arg0
v.argstorage[1] = arg1
v.argstorage[2] = arg2
arg0.Uses++
arg1.Uses++
arg2.Uses++
return v
}

// NewValue4 returns a new value in the block with four arguments and zero aux values.
func (b *Block) NewValue4(pos src.XPos, op Op, t Type, arg0, arg1, arg2, arg3 *Value) *Value {
v := b.Func.newValue(op, t, b, pos)
Expand Down
Loading

0 comments on commit c8f38b3

Please sign in to comment.