mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] cmd/compile: small optimization to prove using sdom tweak
Exposed data already in sdom to avoid recreating it in prove. Change-Id: I834c9c03ed8faeaee013e5a1b3f955908f0e0915 Reviewed-on: https://go-review.googlesource.com/19999 Run-TryBot: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alexandru Moșoi <alexandru@mosoi.ro>
This commit is contained in:
parent
bdea1d58cf
commit
34f048c9d9
2 changed files with 19 additions and 11 deletions
|
|
@ -127,14 +127,6 @@ var (
|
||||||
func prove(f *Func) {
|
func prove(f *Func) {
|
||||||
idom := dominators(f)
|
idom := dominators(f)
|
||||||
sdom := newSparseTree(f, idom)
|
sdom := newSparseTree(f, idom)
|
||||||
domTree := make([][]*Block, f.NumBlocks())
|
|
||||||
|
|
||||||
// Create a block ID -> [dominees] mapping
|
|
||||||
for _, b := range f.Blocks {
|
|
||||||
if dom := idom[b.ID]; dom != nil {
|
|
||||||
domTree[dom.ID] = append(domTree[dom.ID], b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// current node state
|
// current node state
|
||||||
type walkState int
|
type walkState int
|
||||||
|
|
@ -179,7 +171,7 @@ func prove(f *Func) {
|
||||||
saved: saved,
|
saved: saved,
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, s := range domTree[node.block.ID] {
|
for s := sdom.Child(node.block); s != nil; s = sdom.Sibling(s) {
|
||||||
work = append(work, bp{
|
work = append(work, bp{
|
||||||
block: s,
|
block: s,
|
||||||
state: descend,
|
state: descend,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
package ssa
|
package ssa
|
||||||
|
|
||||||
type sparseTreeNode struct {
|
type sparseTreeNode struct {
|
||||||
block *Block
|
|
||||||
child *Block
|
child *Block
|
||||||
sibling *Block
|
sibling *Block
|
||||||
parent *Block
|
parent *Block
|
||||||
|
|
@ -43,7 +42,6 @@ func newSparseTree(f *Func, parentOf []*Block) sparseTree {
|
||||||
t := make(sparseTree, f.NumBlocks())
|
t := make(sparseTree, f.NumBlocks())
|
||||||
for _, b := range f.Blocks {
|
for _, b := range f.Blocks {
|
||||||
n := &t[b.ID]
|
n := &t[b.ID]
|
||||||
n.block = b
|
|
||||||
if p := parentOf[b.ID]; p != nil {
|
if p := parentOf[b.ID]; p != nil {
|
||||||
n.parent = p
|
n.parent = p
|
||||||
n.sibling = t[p.ID].child
|
n.sibling = t[p.ID].child
|
||||||
|
|
@ -98,6 +96,24 @@ func (t sparseTree) numberBlock(b *Block, n int32) int32 {
|
||||||
return n + 2
|
return n + 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sibling returns a sibling of x in the dominator tree (i.e.,
|
||||||
|
// a node with the same immediate dominator) or nil if there
|
||||||
|
// are no remaining siblings in the arbitrary but repeatable
|
||||||
|
// order chosen. Because the Child-Sibling order is used
|
||||||
|
// to assign entry and exit numbers in the treewalk, those
|
||||||
|
// numbers are also consistent with this order (i.e.,
|
||||||
|
// Sibling(x) has entry number larger than x's exit number).
|
||||||
|
func (t sparseTree) Sibling(x *Block) *Block {
|
||||||
|
return t[x.ID].sibling
|
||||||
|
}
|
||||||
|
|
||||||
|
// Child returns a child of x in the dominator tree, or
|
||||||
|
// nil if there are none. The choice of first child is
|
||||||
|
// arbitrary but repeatable.
|
||||||
|
func (t sparseTree) Child(x *Block) *Block {
|
||||||
|
return t[x.ID].child
|
||||||
|
}
|
||||||
|
|
||||||
// isAncestorEq reports whether x is an ancestor of or equal to y.
|
// isAncestorEq reports whether x is an ancestor of or equal to y.
|
||||||
func (t sparseTree) isAncestorEq(x, y *Block) bool {
|
func (t sparseTree) isAncestorEq(x, y *Block) bool {
|
||||||
xx := &t[x.ID]
|
xx := &t[x.ID]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue