1
0
mirror of https://github.com/golang/go synced 2024-09-28 22:24:29 -06:00

[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.
v.budget++
case ir.OCALLPART:
case ir.OCALLPART, ir.OSLICELIT:
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)
o.exprList(n.List())
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)
}
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:
r := r.(*ir.CompLitExpr)
// copy slice
slicesym(l, loff, s.inittemps[r], ir.Int64Val(r.Right()))
slicesym(l, loff, s.inittemps[r], r.Len)
return true
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:
r := r.(*ir.CompLitExpr)
s.initplan(r)
// Init slice.
bound := ir.Int64Val(r.Right())
ta := types.NewArray(r.Type().Elem(), bound)
ta := types.NewArray(r.Type().Elem(), r.Len)
ta.SetNoalg(true)
a := staticname(ta)
s.inittemps[r] = a
slicesym(l, loff, a, bound)
slicesym(l, loff, a, r.Len)
// Fall through to init underlying array.
l = a
loff = 0
@ -425,10 +426,11 @@ func getdyn(n ir.Node, top bool) initGenType {
return initDynamic
case ir.OSLICELIT:
n := n.(*ir.CompLitExpr)
if !top {
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.
// Very rough estimation, it takes 4 bytes of instructions
// to initialize 1 byte of result. So don't use a static
@ -603,14 +605,12 @@ func isSmallSliceLit(n *ir.CompLitExpr) bool {
return false
}
r := n.Right()
return smallintconst(r) && (n.Type().Elem().Width == 0 || ir.Int64Val(r) <= smallArrayBytes/n.Type().Elem().Width)
return n.Type().Elem().Width == 0 || n.Len <= smallArrayBytes/n.Type().Elem().Width
}
func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes) {
// 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)
if ctxt == inNonInitFunction {

View File

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

View File

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