mirror of https://github.com/golang/go.git
[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:
parent
2755361e6a
commit
3512cde10a
|
|
@ -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.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue