func buildDomTree(nodes []*node) {
	for _, b := range nodes {
		b.dom = domInfo{index: -1}
	}
	root := nodes[0]
	var reachable []*node
	var visit func(n *node)
	visit = func(n *node) {
		if n.dom.index < 0 {
			n.dom.index = int32(len(reachable))
			reachable = append(reachable, n)
			for _, imp := range n.imports {
				visit(imp)
			}
		}
	}
	visit(root)
	nodes = reachable
	n := len(nodes)
	space := make([]*node, 5*n)
	lt := ltState{
		sdom:     space[0:n],
		parent:   space[n : 2*n],
		ancestor: space[2*n : 3*n],
	}
	preorder := space[3*n : 4*n]
	lt.dfs(root, 0, preorder)
	buckets := space[4*n : 5*n]
	copy(buckets, preorder)
	for i := int32(n) - 1; i > 0; i-- {
		w := preorder[i]
		for v := buckets[i]; v != w; v = buckets[v.dom.pre] {
			u := lt.eval(v)
			if lt.sdom[u.dom.index].dom.pre < i {
				v.dom.idom = u
			} else {
				v.dom.idom = w
			}
		}
		lt.sdom[w.dom.index] = lt.parent[w.dom.index]
		for _, v := range w.importedBy {
			if v.dom.index < 0 {
				continue  
			}
			u := lt.eval(v)
			if lt.sdom[u.dom.index].dom.pre < lt.sdom[w.dom.index].dom.pre {
				lt.sdom[w.dom.index] = lt.sdom[u.dom.index]
			}
		}
		lt.link(lt.parent[w.dom.index], w)
		if lt.parent[w.dom.index] == lt.sdom[w.dom.index] {
			w.dom.idom = lt.parent[w.dom.index]
		} else {
			buckets[i] = buckets[lt.sdom[w.dom.index].dom.pre]
			buckets[lt.sdom[w.dom.index].dom.pre] = w
		}
	}
	for v := buckets[0]; v != preorder[0]; v = buckets[v.dom.pre] {
		v.dom.idom = preorder[0]
	}
	for _, w := range preorder[1:] {
		if w == root {
			w.dom.idom = nil
		} else {
			if w.dom.idom != lt.sdom[w.dom.index] {
				w.dom.idom = w.dom.idom.dom.idom
			}
			w.dom.idom.dom.children = append(w.dom.idom.dom.children, w)
		}
	}
	numberDomTree(root, 0, 0)
}
buildDomTree computes the dominator tree of f using the LT algorithm.
The first node is the distinguished root node.
package main
func (b *node) Idom() *node { return b.dom.idom }
func (b *node) Dominees() []*node { return b.dom.children }
func (b *node) Dominates(c *node) bool {
	return b.dom.pre <= c.dom.pre && c.dom.post <= b.dom.post
}
type domInfo struct {
	idom      *node    
	children  []*node  
	pre, post int32    
	index     int32    
}
type ltState struct {
	sdom     []*node  
	parent   []*node  
	ancestor []*node  
}
func (lt *ltState) dfs(v *node, i int32, preorder []*node) int32 {
	preorder[i] = v
	v.dom.pre = i  
	i++
	lt.sdom[v.dom.index] = v
	lt.link(nil, v)
	for _, w := range v.imports {
		if lt.sdom[w.dom.index] == nil {
			lt.parent[w.dom.index] = v
			i = lt.dfs(w, i, preorder)
		}
	}
	return i
}
func (lt *ltState) eval(v *node) *node {
	u := v
	for ; lt.ancestor[v.dom.index] != nil; v = lt.ancestor[v.dom.index] {
		if lt.sdom[v.dom.index].dom.pre < lt.sdom[u.dom.index].dom.pre {
			u = v
		}
	}
	return u
}
func (lt *ltState) link(v, w *node) {
	lt.ancestor[w.dom.index] = v
}