mirror of
https://github.com/golang/go
synced 2024-11-23 16:40:03 -07:00
cmd/compile: remove dynamic entry handling from sinit/maplit
The order pass now handles all the dynamic entries. Update #26552 Followup to CL 174417 Change-Id: Ie924cadb0e0ba36c423868f654f13040100b44c6 Reviewed-on: https://go-review.googlesource.com/c/go/+/174498 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
70b890ce3b
commit
85387aa364
@ -650,6 +650,8 @@ func getdyn(n *Node, top bool) initGenType {
|
|||||||
// isStaticCompositeLiteral reports whether n is a compile-time constant.
|
// isStaticCompositeLiteral reports whether n is a compile-time constant.
|
||||||
func isStaticCompositeLiteral(n *Node) bool {
|
func isStaticCompositeLiteral(n *Node) bool {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
|
case ONAME:
|
||||||
|
return n.Class() == PEXTERN && n.Name != nil && n.Name.Readonly()
|
||||||
case OSLICELIT:
|
case OSLICELIT:
|
||||||
return false
|
return false
|
||||||
case OARRAYLIT:
|
case OARRAYLIT:
|
||||||
@ -954,26 +956,22 @@ func maplit(n *Node, m *Node, init *Nodes) {
|
|||||||
a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))
|
a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))
|
||||||
litas(m, a, init)
|
litas(m, a, init)
|
||||||
|
|
||||||
// Split the initializers into static and dynamic.
|
entries := n.List.Slice()
|
||||||
var stat, dyn []*Node
|
|
||||||
for _, r := range n.List.Slice() {
|
// The order pass already removed any dynamic (runtime-computed) entries.
|
||||||
if r.Op != OKEY {
|
// All remaining entries are static. Double-check that.
|
||||||
Fatalf("maplit: rhs not OKEY: %v", r)
|
for _, r := range entries {
|
||||||
}
|
if !isStaticCompositeLiteral(r.Left) || !isStaticCompositeLiteral(r.Right) {
|
||||||
if isStaticCompositeLiteral(r.Left) && isStaticCompositeLiteral(r.Right) {
|
Fatalf("maplit: entry is not a literal: %v", r)
|
||||||
stat = append(stat, r)
|
|
||||||
} else {
|
|
||||||
dyn = append(dyn, r)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add static entries.
|
if len(entries) > 25 {
|
||||||
if len(stat) > 25 {
|
// For a large number of entries, put them in an array and loop.
|
||||||
// For a large number of static entries, put them in an array and loop.
|
|
||||||
|
|
||||||
// build types [count]Tindex and [count]Tvalue
|
// build types [count]Tindex and [count]Tvalue
|
||||||
tk := types.NewArray(n.Type.Key(), int64(len(stat)))
|
tk := types.NewArray(n.Type.Key(), int64(len(entries)))
|
||||||
te := types.NewArray(n.Type.Elem(), int64(len(stat)))
|
te := types.NewArray(n.Type.Elem(), int64(len(entries)))
|
||||||
|
|
||||||
// TODO(josharian): suppress alg generation for these types?
|
// TODO(josharian): suppress alg generation for these types?
|
||||||
dowidth(tk)
|
dowidth(tk)
|
||||||
@ -987,7 +985,7 @@ func maplit(n *Node, m *Node, init *Nodes) {
|
|||||||
|
|
||||||
datak := nod(OARRAYLIT, nil, nil)
|
datak := nod(OARRAYLIT, nil, nil)
|
||||||
datae := nod(OARRAYLIT, nil, nil)
|
datae := nod(OARRAYLIT, nil, nil)
|
||||||
for _, r := range stat {
|
for _, r := range entries {
|
||||||
datak.List.Append(r.Left)
|
datak.List.Append(r.Left)
|
||||||
datae.List.Append(r.Right)
|
datae.List.Append(r.Right)
|
||||||
}
|
}
|
||||||
@ -1018,21 +1016,9 @@ func maplit(n *Node, m *Node, init *Nodes) {
|
|||||||
loop = typecheck(loop, ctxStmt)
|
loop = typecheck(loop, ctxStmt)
|
||||||
loop = walkstmt(loop)
|
loop = walkstmt(loop)
|
||||||
init.Append(loop)
|
init.Append(loop)
|
||||||
} else {
|
|
||||||
// For a small number of static entries, just add them directly.
|
|
||||||
addMapEntries(m, stat, init)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add dynamic entries.
|
|
||||||
addMapEntries(m, dyn, init)
|
|
||||||
}
|
|
||||||
|
|
||||||
func addMapEntries(m *Node, dyn []*Node, init *Nodes) {
|
|
||||||
if len(dyn) == 0 {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// For a small number of entries, just add them directly.
|
||||||
nerr := nerrors
|
|
||||||
|
|
||||||
// Build list of var[c] = expr.
|
// Build list of var[c] = expr.
|
||||||
// Use temporaries so that mapassign1 can have addressable key, elem.
|
// Use temporaries so that mapassign1 can have addressable key, elem.
|
||||||
@ -1040,7 +1026,7 @@ func addMapEntries(m *Node, dyn []*Node, init *Nodes) {
|
|||||||
tmpkey := temp(m.Type.Key())
|
tmpkey := temp(m.Type.Key())
|
||||||
tmpelem := temp(m.Type.Elem())
|
tmpelem := temp(m.Type.Elem())
|
||||||
|
|
||||||
for _, r := range dyn {
|
for _, r := range entries {
|
||||||
index, elem := r.Left, r.Right
|
index, elem := r.Left, r.Right
|
||||||
|
|
||||||
setlineno(index)
|
setlineno(index)
|
||||||
@ -1060,13 +1046,9 @@ func addMapEntries(m *Node, dyn []*Node, init *Nodes) {
|
|||||||
a = typecheck(a, ctxStmt)
|
a = typecheck(a, ctxStmt)
|
||||||
a = walkstmt(a)
|
a = walkstmt(a)
|
||||||
init.Append(a)
|
init.Append(a)
|
||||||
|
|
||||||
if nerr != nerrors {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a := nod(OVARKILL, tmpkey, nil)
|
a = nod(OVARKILL, tmpkey, nil)
|
||||||
a = typecheck(a, ctxStmt)
|
a = typecheck(a, ctxStmt)
|
||||||
init.Append(a)
|
init.Append(a)
|
||||||
a = nod(OVARKILL, tmpelem, nil)
|
a = nod(OVARKILL, tmpelem, nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user