[dev.regabi] cmd/compile: stop reusing Ntype for OSLICELIT length

For OSLICELITs, we were reusing the Ntype field after type checking to
hold the length of the OSLICELIT's backing array. However, Ntype is
only meant for nodes that can represent types. Today, this works only
because we currently use Name for all OLITERAL constants (whether
declared or not), whereas we should be able to represent them more
compactly with a dedicated type that doesn't implement Ntype.

Passes buildall w/ toolstash -cmp.

Change-Id: I385f1d787c41b016f507a5bad9489d59ccfde7f2
Reviewed-on: https://go-review.googlesource.com/c/go/+/279152
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Matthew Dempsky 2020-12-17 18:47:26 -08:00
parent 2755361e6a
commit 3512cde10a
5 changed files with 14 additions and 12 deletions

View File

@ -452,7 +452,7 @@ func (v *hairyVisitor) doNode(n ir.Node) error {
// and don't charge for the OBLOCK itself. The ++ undoes the -- below. // and don't charge for the OBLOCK itself. The ++ undoes the -- below.
v.budget++ v.budget++
case ir.OCALLPART: case ir.OCALLPART, ir.OSLICELIT:
v.budget-- // Hack for toolstash -cmp. v.budget-- // Hack for toolstash -cmp.
} }

View File

@ -1281,7 +1281,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
n := n.(*ir.CompLitExpr) n := n.(*ir.CompLitExpr)
o.exprList(n.List()) o.exprList(n.List())
if n.Transient() { if n.Transient() {
t := types.NewArray(n.Type().Elem(), ir.Int64Val(n.Right())) t := types.NewArray(n.Type().Elem(), n.Len)
n.Prealloc = o.newTemp(t, false) n.Prealloc = o.newTemp(t, false)
} }
return n return n

View File

@ -142,8 +142,9 @@ func (s *InitSchedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *type
} }
case ir.OSLICELIT: case ir.OSLICELIT:
r := r.(*ir.CompLitExpr)
// copy slice // copy slice
slicesym(l, loff, s.inittemps[r], ir.Int64Val(r.Right())) slicesym(l, loff, s.inittemps[r], r.Len)
return true return true
case ir.OARRAYLIT, ir.OSTRUCTLIT: case ir.OARRAYLIT, ir.OSTRUCTLIT:
@ -232,14 +233,14 @@ func (s *InitSchedule) staticassign(l *ir.Name, loff int64, r ir.Node, typ *type
} }
case ir.OSLICELIT: case ir.OSLICELIT:
r := r.(*ir.CompLitExpr)
s.initplan(r) s.initplan(r)
// Init slice. // Init slice.
bound := ir.Int64Val(r.Right()) ta := types.NewArray(r.Type().Elem(), r.Len)
ta := types.NewArray(r.Type().Elem(), bound)
ta.SetNoalg(true) ta.SetNoalg(true)
a := staticname(ta) a := staticname(ta)
s.inittemps[r] = a s.inittemps[r] = a
slicesym(l, loff, a, bound) slicesym(l, loff, a, r.Len)
// Fall through to init underlying array. // Fall through to init underlying array.
l = a l = a
loff = 0 loff = 0
@ -425,10 +426,11 @@ func getdyn(n ir.Node, top bool) initGenType {
return initDynamic return initDynamic
case ir.OSLICELIT: case ir.OSLICELIT:
n := n.(*ir.CompLitExpr)
if !top { if !top {
return initDynamic return initDynamic
} }
if ir.Int64Val(n.Right())/4 > int64(n.List().Len()) { if n.Len/4 > int64(n.List().Len()) {
// <25% of entries have explicit values. // <25% of entries have explicit values.
// Very rough estimation, it takes 4 bytes of instructions // Very rough estimation, it takes 4 bytes of instructions
// to initialize 1 byte of result. So don't use a static // to initialize 1 byte of result. So don't use a static
@ -603,14 +605,12 @@ func isSmallSliceLit(n *ir.CompLitExpr) bool {
return false return false
} }
r := n.Right() return n.Type().Elem().Width == 0 || n.Len <= smallArrayBytes/n.Type().Elem().Width
return smallintconst(r) && (n.Type().Elem().Width == 0 || ir.Int64Val(r) <= smallArrayBytes/n.Type().Elem().Width)
} }
func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) { func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) {
// make an array type corresponding the number of elements we have // make an array type corresponding the number of elements we have
t := types.NewArray(n.Type().Elem(), ir.Int64Val(n.Right())) t := types.NewArray(n.Type().Elem(), n.Len)
dowidth(t) dowidth(t)
if ctxt == inNonInitFunction { if ctxt == inNonInitFunction {

View File

@ -2850,7 +2850,8 @@ func typecheckcomplit(n *ir.CompLitExpr) (res ir.Node) {
case types.TSLICE: case types.TSLICE:
length := typecheckarraylit(t.Elem(), -1, n.List().Slice(), "slice literal") length := typecheckarraylit(t.Elem(), -1, n.List().Slice(), "slice literal")
n.SetOp(ir.OSLICELIT) n.SetOp(ir.OSLICELIT)
n.SetRight(nodintconst(length)) n.SetRight(nil)
n.Len = length
case types.TMAP: case types.TMAP:
var cs constSet var cs constSet

View File

@ -294,6 +294,7 @@ type CompLitExpr struct {
Ntype Ntype Ntype Ntype
List_ Nodes // initialized values List_ Nodes // initialized values
Prealloc *Name Prealloc *Name
Len int64 // backing array length for OSLICELIT
} }
func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr { func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr {