mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: move Node.Walkdef into flags
Node.Walkdef is 0, 1, or 2, so it only requires two bits. Add support for 2-bit values to bitset, and use it for Node.Walkdef. Class, Embedded, Typecheck, and Initorder will follow suit in subsequent CLs. The multi-bit flags will go at the beginning, since that generates (marginally) more efficient code. Change-Id: Id6e2e66e437f10aaa05b8a6e1652efb327d06128 Reviewed-on: https://go-review.googlesource.com/41791 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
804784c8ba
commit
d286399641
4 changed files with 43 additions and 27 deletions
|
|
@ -23,3 +23,14 @@ func (f *bitset32) set(mask uint32, b bool) {
|
||||||
*(*uint32)(f) &^= mask
|
*(*uint32)(f) &^= mask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f bitset32) get2(shift uint8) uint8 {
|
||||||
|
return uint8(f>>shift) & 3
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *bitset32) set2(shift uint8, b uint8) {
|
||||||
|
// Clear old bits.
|
||||||
|
*(*uint32)(f) &^= 3 << shift
|
||||||
|
// Set new bits.
|
||||||
|
*(*uint32)(f) |= uint32(b) << shift
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func TestSizeof(t *testing.T) {
|
||||||
{Func{}, 100, 168},
|
{Func{}, 100, 168},
|
||||||
{Name{}, 36, 56},
|
{Name{}, 36, 56},
|
||||||
{Param{}, 28, 56},
|
{Param{}, 28, 56},
|
||||||
{Node{}, 84, 136},
|
{Node{}, 80, 136},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ type Node struct {
|
||||||
Etype types.EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN, for OINDEXMAP 1=LHS,0=RHS
|
Etype types.EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN, for OINDEXMAP 1=LHS,0=RHS
|
||||||
Class Class // PPARAM, PAUTO, PEXTERN, etc
|
Class Class // PPARAM, PAUTO, PEXTERN, etc
|
||||||
Embedded uint8 // ODCLFIELD embedded type
|
Embedded uint8 // ODCLFIELD embedded type
|
||||||
Walkdef uint8 // tracks state during typecheckdef; 2 == loop detected
|
|
||||||
Typecheck uint8 // tracks state during typechecking; 2 == loop detected
|
Typecheck uint8 // tracks state during typechecking; 2 == loop detected
|
||||||
Initorder uint8
|
Initorder uint8
|
||||||
}
|
}
|
||||||
|
|
@ -74,28 +73,32 @@ func (n *Node) IsAutoTmp() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
nodeHasBreak = 1 << iota
|
nodeWalkdef, _ = iota, 1 << iota // tracks state during typecheckdef; 2 == loop detected; two bits
|
||||||
nodeIsClosureVar
|
_, _ // second nodeWalkdef bit
|
||||||
nodeIsOutputParamHeapAddr
|
_, nodeHasBreak
|
||||||
nodeNoInline // used internally by inliner to indicate that a function call should not be inlined; set for OCALLFUNC and OCALLMETH only
|
_, nodeIsClosureVar
|
||||||
nodeAssigned // is the variable ever assigned to
|
_, nodeIsOutputParamHeapAddr
|
||||||
nodeAddrtaken // address taken, even if not moved to heap
|
_, nodeNoInline // used internally by inliner to indicate that a function call should not be inlined; set for OCALLFUNC and OCALLMETH only
|
||||||
nodeImplicit
|
_, nodeAssigned // is the variable ever assigned to
|
||||||
nodeIsddd // is the argument variadic
|
_, nodeAddrtaken // address taken, even if not moved to heap
|
||||||
nodeLocal // type created in this file (see also Type.Local)
|
_, nodeImplicit
|
||||||
nodeDiag // already printed error about this
|
_, nodeIsddd // is the argument variadic
|
||||||
nodeColas // OAS resulting from :=
|
_, nodeLocal // type created in this file (see also Type.Local)
|
||||||
nodeNonNil // guaranteed to be non-nil
|
_, nodeDiag // already printed error about this
|
||||||
nodeNoescape // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
|
_, nodeColas // OAS resulting from :=
|
||||||
nodeBounded // bounds check unnecessary
|
_, nodeNonNil // guaranteed to be non-nil
|
||||||
nodeAddable // addressable
|
_, nodeNoescape // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
|
||||||
nodeUsed // for variable/label declared and not used error
|
_, nodeBounded // bounds check unnecessary
|
||||||
nodeHasCall // expression contains a function call
|
_, nodeAddable // addressable
|
||||||
nodeLikely // if statement condition likely
|
_, nodeUsed // for variable/label declared and not used error
|
||||||
nodeHasVal // node.E contains a Val
|
_, nodeHasCall // expression contains a function call
|
||||||
nodeHasOpt // node.E contains an Opt
|
_, nodeLikely // if statement condition likely
|
||||||
|
_, nodeHasVal // node.E contains a Val
|
||||||
|
_, nodeHasOpt // node.E contains an Opt
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (n *Node) Walkdef() uint8 { return n.flags.get2(nodeWalkdef) }
|
||||||
|
|
||||||
func (n *Node) HasBreak() bool { return n.flags&nodeHasBreak != 0 }
|
func (n *Node) HasBreak() bool { return n.flags&nodeHasBreak != 0 }
|
||||||
func (n *Node) IsClosureVar() bool { return n.flags&nodeIsClosureVar != 0 }
|
func (n *Node) IsClosureVar() bool { return n.flags&nodeIsClosureVar != 0 }
|
||||||
func (n *Node) NoInline() bool { return n.flags&nodeNoInline != 0 }
|
func (n *Node) NoInline() bool { return n.flags&nodeNoInline != 0 }
|
||||||
|
|
@ -117,6 +120,8 @@ func (n *Node) Likely() bool { return n.flags&nodeLikely != 0 }
|
||||||
func (n *Node) HasVal() bool { return n.flags&nodeHasVal != 0 }
|
func (n *Node) HasVal() bool { return n.flags&nodeHasVal != 0 }
|
||||||
func (n *Node) HasOpt() bool { return n.flags&nodeHasOpt != 0 }
|
func (n *Node) HasOpt() bool { return n.flags&nodeHasOpt != 0 }
|
||||||
|
|
||||||
|
func (n *Node) SetWalkdef(b uint8) { n.flags.set2(nodeWalkdef, b) }
|
||||||
|
|
||||||
func (n *Node) SetHasBreak(b bool) { n.flags.set(nodeHasBreak, b) }
|
func (n *Node) SetHasBreak(b bool) { n.flags.set(nodeHasBreak, b) }
|
||||||
func (n *Node) SetIsClosureVar(b bool) { n.flags.set(nodeIsClosureVar, b) }
|
func (n *Node) SetIsClosureVar(b bool) { n.flags.set(nodeIsClosureVar, b) }
|
||||||
func (n *Node) SetNoInline(b bool) { n.flags.set(nodeNoInline, b) }
|
func (n *Node) SetNoInline(b bool) { n.flags.set(nodeNoInline, b) }
|
||||||
|
|
|
||||||
|
|
@ -3628,12 +3628,12 @@ func typecheckdef(n *Node) *Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Walkdef == 1 {
|
if n.Walkdef() == 1 {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
typecheckdefstack = append(typecheckdefstack, n)
|
typecheckdefstack = append(typecheckdefstack, n)
|
||||||
if n.Walkdef == 2 {
|
if n.Walkdef() == 2 {
|
||||||
flusherrors()
|
flusherrors()
|
||||||
fmt.Printf("typecheckdef loop:")
|
fmt.Printf("typecheckdef loop:")
|
||||||
for i := len(typecheckdefstack) - 1; i >= 0; i-- {
|
for i := len(typecheckdefstack) - 1; i >= 0; i-- {
|
||||||
|
|
@ -3644,7 +3644,7 @@ func typecheckdef(n *Node) *Node {
|
||||||
Fatalf("typecheckdef loop")
|
Fatalf("typecheckdef loop")
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Walkdef = 2
|
n.SetWalkdef(2)
|
||||||
|
|
||||||
if n.Type != nil || n.Sym == nil { // builtin or no name
|
if n.Type != nil || n.Sym == nil { // builtin or no name
|
||||||
goto ret
|
goto ret
|
||||||
|
|
@ -3766,7 +3766,7 @@ func typecheckdef(n *Node) *Node {
|
||||||
if Curfn != nil {
|
if Curfn != nil {
|
||||||
defercheckwidth()
|
defercheckwidth()
|
||||||
}
|
}
|
||||||
n.Walkdef = 1
|
n.SetWalkdef(1)
|
||||||
n.Type = types.New(TFORW)
|
n.Type = types.New(TFORW)
|
||||||
n.Type.Nod = asTypesNode(n)
|
n.Type.Nod = asTypesNode(n)
|
||||||
n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen?
|
n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen?
|
||||||
|
|
@ -3794,7 +3794,7 @@ ret:
|
||||||
typecheckdefstack = typecheckdefstack[:last]
|
typecheckdefstack = typecheckdefstack[:last]
|
||||||
|
|
||||||
lineno = lno
|
lineno = lno
|
||||||
n.Walkdef = 1
|
n.SetWalkdef(1)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue