idom := f.Idom()
po := f.postorder()
- // The ordering in the dominator tree matters; it's important that
- // the walk of the dominator tree also be a preorder (i.e., a node is
- // visited only after all its non-backedge predecessors have been visited).
- sdom := newSparseOrderedTree(f, idom, po)
+ sdom := f.Sdom()
if f.pass.debug > 1 {
fmt.Printf("before %s = %s\n", f.Name, sdom.treestructure(f.Entry))
type SparseTree []SparseTreeNode
// newSparseTree creates a SparseTree from a block-to-parent map (array indexed by Block.ID).
+// The children of a given node are in reverse postorder.
+// This has the nice property that for a given tree walk, the source block of all
+// non-retreating edges are visited before their destination block.
func newSparseTree(f *Func, parentOf []*Block) SparseTree {
+ po := f.postorder()
t := make(SparseTree, f.NumBlocks())
- for _, b := range f.Blocks {
- n := &t[b.ID]
- if p := parentOf[b.ID]; p != nil {
- n.parent = p
- n.sibling = t[p.ID].child
- t[p.ID].child = b
- }
- }
- t.numberBlock(f.Entry, 1)
- return t
-}
-
-// newSparseOrderedTree creates a SparseTree from a block-to-parent map (array indexed by Block.ID)
-// children will appear in the reverse of their order in reverseOrder
-// in particular, if reverseOrder is a dfs-reversePostOrder, then the root-to-children
-// walk of the tree will yield a pre-order.
-func newSparseOrderedTree(f *Func, parentOf, reverseOrder []*Block) SparseTree {
- t := make(SparseTree, f.NumBlocks())
- for _, b := range reverseOrder {
+ for _, b := range po {
n := &t[b.ID]
if p := parentOf[b.ID]; p != nil {
n.parent = p