mirror of
https://github.com/golang/go
synced 2024-11-11 20:50:23 -07:00
[dev.regabi] cmd/compile: remove prealloc map
The prealloc map seems to exist to avoid adding a field to all nodes. Now we can add a field to just the nodes that need the field, so let's do that and avoid having a magic global with extra node state that isn't preserved by operations like Copy nor printed by Dump. This also makes clear which nodes can be prealloc'ed. In particular, the code in walkstmt looked up an entry in prealloc using an ONAME node, but there's no code that ever stores such an entry, so the lookup never succeeded. Having fields makes that kind of thing easier to see and fix. Passes buildall w/ toolstash -cmp. Change-Id: I418ad0e2847615c08868120c13ee719dc0b2eacb Reviewed-on: https://go-review.googlesource.com/c/go/+/278915 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
ffb0cb7044
commit
c45313bf45
@ -378,7 +378,7 @@ func closureType(clo ir.Node) *types.Type {
|
||||
return typ
|
||||
}
|
||||
|
||||
func walkclosure(clo ir.Node, init *ir.Nodes) ir.Node {
|
||||
func walkclosure(clo *ir.ClosureExpr, init *ir.Nodes) ir.Node {
|
||||
fn := clo.Func()
|
||||
|
||||
// If no closure vars, don't bother wrapping.
|
||||
@ -403,12 +403,12 @@ func walkclosure(clo ir.Node, init *ir.Nodes) ir.Node {
|
||||
cfn := convnop(addr, clo.Type())
|
||||
|
||||
// non-escaping temp to use, if any.
|
||||
if x := prealloc[clo]; x != nil {
|
||||
if x := clo.Prealloc; x != nil {
|
||||
if !types.Identical(typ, x.Type()) {
|
||||
panic("closure type does not match order's assigned type")
|
||||
}
|
||||
addr.SetRight(x)
|
||||
delete(prealloc, clo)
|
||||
clo.Prealloc = nil
|
||||
}
|
||||
|
||||
return walkexpr(cfn, init)
|
||||
@ -552,12 +552,12 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
|
||||
cfn := convnop(addr, n.Type())
|
||||
|
||||
// non-escaping temp to use, if any.
|
||||
if x := prealloc[n]; x != nil {
|
||||
if x := n.Prealloc; x != nil {
|
||||
if !types.Identical(typ, x.Type()) {
|
||||
panic("partial call type does not match order's assigned type")
|
||||
}
|
||||
addr.SetRight(x)
|
||||
delete(prealloc, n)
|
||||
n.Prealloc = nil
|
||||
}
|
||||
|
||||
return walkexpr(cfn, init)
|
||||
|
@ -846,9 +846,9 @@ func (o *Order) stmt(n ir.Node) {
|
||||
r := n.Right()
|
||||
n.SetRight(o.copyExpr(r))
|
||||
|
||||
// prealloc[n] is the temp for the iterator.
|
||||
// n.Prealloc is the temp for the iterator.
|
||||
// hiter contains pointers and needs to be zeroed.
|
||||
prealloc[n] = o.newTemp(hiter(n.Type()), true)
|
||||
n.Prealloc = o.newTemp(hiter(n.Type()), true)
|
||||
}
|
||||
o.exprListInPlace(n.List())
|
||||
if orderBody {
|
||||
@ -1040,9 +1040,6 @@ func (o *Order) exprListInPlace(l ir.Nodes) {
|
||||
}
|
||||
}
|
||||
|
||||
// prealloc[x] records the allocation to use for x.
|
||||
var prealloc = map[ir.Node]ir.Node{}
|
||||
|
||||
func (o *Order) exprNoLHS(n ir.Node) ir.Node {
|
||||
return o.expr(n, nil)
|
||||
}
|
||||
@ -1079,11 +1076,12 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
|
||||
// Allocate a temporary to hold the strings.
|
||||
// Fewer than 5 strings use direct runtime helpers.
|
||||
case ir.OADDSTR:
|
||||
n := n.(*ir.AddStringExpr)
|
||||
o.exprList(n.List())
|
||||
|
||||
if n.List().Len() > 5 {
|
||||
t := types.NewArray(types.Types[types.TSTRING], int64(n.List().Len()))
|
||||
prealloc[n] = o.newTemp(t, false)
|
||||
n.Prealloc = o.newTemp(t, false)
|
||||
}
|
||||
|
||||
// Mark string(byteSlice) arguments to reuse byteSlice backing
|
||||
@ -1268,7 +1266,7 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
|
||||
case ir.OCLOSURE:
|
||||
n := n.(*ir.ClosureExpr)
|
||||
if n.Transient() && len(n.Func().ClosureVars) > 0 {
|
||||
prealloc[n] = o.newTemp(closureType(n), false)
|
||||
n.Prealloc = o.newTemp(closureType(n), false)
|
||||
}
|
||||
return n
|
||||
|
||||
@ -1277,15 +1275,16 @@ func (o *Order) expr1(n, lhs ir.Node) ir.Node {
|
||||
n.SetLeft(o.expr(n.Left(), nil))
|
||||
if n.Transient() {
|
||||
t := partialCallType(n)
|
||||
prealloc[n] = o.newTemp(t, false)
|
||||
n.Prealloc = o.newTemp(t, false)
|
||||
}
|
||||
return n
|
||||
|
||||
case ir.OSLICELIT:
|
||||
n := n.(*ir.CompLitExpr)
|
||||
o.exprList(n.List())
|
||||
if n.Transient() {
|
||||
t := types.NewArray(n.Type().Elem(), ir.Int64Val(n.Right()))
|
||||
prealloc[n] = o.newTemp(t, false)
|
||||
n.Prealloc = o.newTemp(t, false)
|
||||
}
|
||||
return n
|
||||
|
||||
|
@ -296,7 +296,7 @@ func walkrange(nrange *ir.RangeStmt) ir.Node {
|
||||
// we only use a once, so no copy needed.
|
||||
ha := a
|
||||
|
||||
hit := prealloc[nrange]
|
||||
hit := nrange.Prealloc
|
||||
th := hit.Type()
|
||||
keysym := th.Field(0).Sym // depends on layout of iterator struct. See reflect.go:hiter
|
||||
elemsym := th.Field(1).Sym // ditto
|
||||
|
@ -668,7 +668,7 @@ func slicelit(ctxt initContext, n *ir.CompLitExpr, var_ ir.Node, init *ir.Nodes)
|
||||
|
||||
// set auto to point at new temp or heap (3 assign)
|
||||
var a ir.Node
|
||||
if x := prealloc[n]; x != nil {
|
||||
if x := n.Prealloc; x != nil {
|
||||
// temp allocated during order.go for dddarg
|
||||
if !types.Identical(t, x.Type()) {
|
||||
panic("dotdotdot base type does not match order's assigned type")
|
||||
|
@ -202,10 +202,7 @@ func walkstmt(n ir.Node) ir.Node {
|
||||
if base.Flag.CompilingRuntime {
|
||||
base.Errorf("%v escapes to heap, not allowed in runtime", v)
|
||||
}
|
||||
if prealloc[v] == nil {
|
||||
prealloc[v] = callnew(v.Type())
|
||||
}
|
||||
nn := ir.Nod(ir.OAS, v.Name().Heapaddr, prealloc[v])
|
||||
nn := ir.Nod(ir.OAS, v.Name().Heapaddr, callnew(v.Type()))
|
||||
nn.SetColas(true)
|
||||
return walkstmt(typecheck(nn, ctxStmt))
|
||||
}
|
||||
@ -1638,7 +1635,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||
return mkcall1(chanfn("chansend1", 2, n.Left().Type()), nil, init, n.Left(), n1)
|
||||
|
||||
case ir.OCLOSURE:
|
||||
return walkclosure(n, init)
|
||||
return walkclosure(n.(*ir.ClosureExpr), init)
|
||||
|
||||
case ir.OCALLPART:
|
||||
return walkpartialcall(n.(*ir.CallPartExpr), init)
|
||||
@ -2713,11 +2710,9 @@ func addstr(n *ir.AddStringExpr, init *ir.Nodes) ir.Node {
|
||||
fn = "concatstrings"
|
||||
|
||||
t := types.NewSlice(types.Types[types.TSTRING])
|
||||
slice := ir.Nod(ir.OCOMPLIT, nil, ir.TypeNode(t))
|
||||
if prealloc[n] != nil {
|
||||
prealloc[slice] = prealloc[n]
|
||||
}
|
||||
slice.PtrList().Set(args[1:]) // skip buf arg
|
||||
// args[1:] to skip buf arg
|
||||
slice := ir.NewCompLitExpr(base.Pos, ir.OCOMPLIT, ir.TypeNode(t), args[1:])
|
||||
slice.Prealloc = n.Prealloc
|
||||
args = []ir.Node{buf, slice}
|
||||
slice.SetEsc(EscNone)
|
||||
}
|
||||
|
@ -89,7 +89,8 @@ func toNtype(x Node) Ntype {
|
||||
// An AddStringExpr is a string concatenation Expr[0] + Exprs[1] + ... + Expr[len(Expr)-1].
|
||||
type AddStringExpr struct {
|
||||
miniExpr
|
||||
List_ Nodes
|
||||
List_ Nodes
|
||||
Prealloc *Name
|
||||
}
|
||||
|
||||
func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
|
||||
@ -233,9 +234,10 @@ func (n *CallExpr) SetOp(op Op) {
|
||||
// A CallPartExpr is a method expression X.Method (uncalled).
|
||||
type CallPartExpr struct {
|
||||
miniExpr
|
||||
Func_ *Func
|
||||
X Node
|
||||
Method *types.Field
|
||||
Func_ *Func
|
||||
X Node
|
||||
Method *types.Field
|
||||
Prealloc *Name
|
||||
}
|
||||
|
||||
func NewCallPartExpr(pos src.XPos, x Node, method *types.Field, fn *Func) *CallPartExpr {
|
||||
@ -255,7 +257,8 @@ func (n *CallPartExpr) SetLeft(x Node) { n.X = x }
|
||||
// A ClosureExpr is a function literal expression.
|
||||
type ClosureExpr struct {
|
||||
miniExpr
|
||||
Func_ *Func
|
||||
Func_ *Func
|
||||
Prealloc *Name
|
||||
}
|
||||
|
||||
func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
|
||||
@ -287,9 +290,10 @@ func (n *ClosureReadExpr) Offset() int64 { return n.Offset_ }
|
||||
// Before type-checking, the type is Ntype.
|
||||
type CompLitExpr struct {
|
||||
miniExpr
|
||||
orig Node
|
||||
Ntype Ntype
|
||||
List_ Nodes // initialized values
|
||||
orig Node
|
||||
Ntype Ntype
|
||||
List_ Nodes // initialized values
|
||||
Prealloc *Name
|
||||
}
|
||||
|
||||
func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr {
|
||||
|
@ -368,6 +368,7 @@ type RangeStmt struct {
|
||||
Body_ Nodes
|
||||
HasBreak_ bool
|
||||
typ *types.Type // TODO(rsc): Remove - use X.Type() instead
|
||||
Prealloc *Name
|
||||
}
|
||||
|
||||
func NewRangeStmt(pos src.XPos, vars []Node, x Node, body []Node) *RangeStmt {
|
||||
|
Loading…
Reference in New Issue
Block a user